Page 1 of 1

Fast copy image pixels to array

Posted: Thu Aug 07, 2008 5:10 am
by Mistrel
This example is adapted from code by Fluid Byte:

http://www.purebasic.fr/english/viewtopic.php?t=26238

Code: Select all

; Fast method of copying pixel data from an image to an array
Procedure CopyImageToArray(ImageID, Array(1))
	Width=ImageWidth(ImageID)
	Height=ImageHeight(ImageID)
	SourceBlock=AllocateMemory(Width*Height*SizeOf(LONG))
	bmi.BITMAPINFO
	bmi\bmiHeader\biSize=SizeOf(BITMAPINFOHEADER)
	bmi\bmiHeader\biWidth=Width
	bmi\bmiHeader\biHeight=Height
	bmi\bmiHeader\biPlanes=1
	bmi\bmiHeader\biBitCount=32
	bmi\bmiHeader\biCompression=#BI_RGB
	hdc=StartDrawing(ImageOutput(ImageID))
	
	; Copy source image to API bitmap structure
	GetDIBits_(hdc,ImageID(ImageID),0,Height,SourceBlock,bmi,#DIB_RGB_COLORS)     
	
	*SourcePixel.LONG=SourceBlock
	
	For i=0 To (Width*Height)-1
		R=*SourcePixel\l&$FF
		G=*SourcePixel\l>>8&$FF
		B=*SourcePixel\l>>16

	; 	*SourcePixel\l=R|G<<8|B<<16
		Array((Width*Height)-(((i/Width)*Width)+Width)+(i%Width))=RGB(B,G,R)
		*SourcePixel+SizeOf(LONG)
	Next
	
	; Copy API bitmap structure back to image ID
	SetDIBits_(hdc,ImageID(ImageID),0,Height,SourceBlock,bmi,#DIB_RGB_COLORS)
	FreeMemory(SourceBlock)
	StopDrawing()
EndProcedure

Procedure CopyArrayToImage(Array(1),ImageID)
	Width=ImageWidth(ImageID)
	Height=ImageHeight(ImageID)
	SourceBlock=AllocateMemory(Width*Height*SizeOf(LONG))
	bmi.BITMAPINFO
	bmi\bmiHeader\biSize=SizeOf(BITMAPINFOHEADER)
	bmi\bmiHeader\biWidth=Width
	bmi\bmiHeader\biHeight=Height
	bmi\bmiHeader\biPlanes=1
	bmi\bmiHeader\biBitCount=32
	bmi\bmiHeader\biCompression=#BI_RGB
	hdc=StartDrawing(ImageOutput(ImageID))
	
	; Copy source image to API bitmap structure
	GetDIBits_(hdc,ImageID(ImageID),0,Height,SourceBlock,bmi,#DIB_RGB_COLORS)     
	
	*SourcePixel.LONG=SourceBlock
	
	For i=0 To (Width*Height)-1
		Color=Array((Width*Height)-(((i/Width)*Width)+Width)+(i%Width))
		*SourcePixel\l=Blue(Color)|Green(Color)<<8|Red(Color)<<16
		*SourcePixel+SizeOf(LONG)
	Next
	
	; Copy API bitmap structure back to image ID
	SetDIBits_(hdc,ImageID(ImageID),0,Height,SourceBlock,bmi,#DIB_RGB_COLORS)
	FreeMemory(SourceBlock)
	StopDrawing()
EndProcedure

Posted: Thu Aug 07, 2008 8:06 am
by Rings
just 2 important marks:

-Windows Only
-32Bit only, means only for 24 or 32 Bits per Pixel Colormodes.

Posted: Thu Aug 07, 2008 8:15 am
by idle
is also this post with routines CopyMemoryToImage

http://www.purebasic.fr/english/viewtop ... orytoimage

windows only too :shock: but using a 32 bit dib will handle any color depth

Posted: Sat Aug 09, 2008 9:05 am
by Mistrel
Thanks for the link, idle. :)

I've updated my original post slightly. The image was being inserted into the array upside down and the RGB values were reversed.

Posted: Wed Apr 08, 2009 10:46 am
by Michael Vogel
Should the code work also with PB4.3?