Fast copy image pixels to array

Share your advanced PureBasic knowledge/code with the community.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Fast copy image pixels to array

Post 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
Last edited by Mistrel on Sat Aug 09, 2008 9:25 am, edited 2 times in total.
User avatar
Rings
Moderator
Moderator
Posts: 1435
Joined: Sat Apr 26, 2003 1:11 am

Post by Rings »

just 2 important marks:

-Windows Only
-32Bit only, means only for 24 or 32 Bits per Pixel Colormodes.
SPAMINATOR NR.1
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Post 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
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post 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.
User avatar
Michael Vogel
Addict
Addict
Posts: 2797
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Post by Michael Vogel »

Should the code work also with PB4.3?
Post Reply