Work on image in memory

Just starting out? Need help? Post your questions and find answers here.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8453
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Also assuming Windows: here's another sample to study and play with. Note the speed of using a structured pointer to manipulate the color bits vs. point/plot:

Code: Select all

Declare Swap24(*bmp.BITMAP) 
Declare Swap24_POINT_PLOT(img) 

; Load the image into memory 
UseJPEGImageDecoder() 
LoadImage(0, #PB_Compiler_Home+"examples\sources\data\r2skin.jpg") 

; Get information about the image 
GetObject_(ImageID(0), SizeOf(BITMAP), @bmp.BITMAP) 

With bmp 
  Debug \bmWidth 
  Debug \bmHeight 
  Debug \bmWidthBytes 
  Debug \bmBitsPixel 
  Debug \bmBits 
EndWith 

OpenWindow(0,0,0,bmp\bmWidth,bmp\bmHeight+70,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
ImageGadget(0,0,0,0,0,ImageID(0)) 
ButtonGadget(1,250,522,200,20,"Swap via structured pointer") 
ButtonGadget(2,50,522,200,20,"Swap via point/plot") 
ProgressBarGadget(3, 0,552,512,20,0,ImageWidth(0)*ImageHeight(0))

disabledebugger

Repeat 
  ev=WaitWindowEvent() 
  Select ev 
    Case #PB_Event_Gadget 
      Select EventGadget() 
        Case 1 
          Swap24(@bmp) 
          SetGadgetState(0,ImageID(0)) 
        Case 2
          Swap24_POINT_PLOT(0) 
          SetGadgetState(0,ImageID(0))
      EndSelect 
  EndSelect 
Until ev=#PB_Event_CloseWindow 

Procedure Swap24(*bmp.BITMAP) 
   SetGadgetState(3,0) : cc=0
   *buffer.RGBTRIPLE = *bmp\bmBits 
   While *buffer <= *bmp\bmBits+*bmp\bmWidthBytes**bmp\bmHeight-SizeOf(RGBTRIPLE) 
     Swap *buffer\rgbtBlue, *buffer\rgbtRed 
     *buffer+SizeOf(RGBTRIPLE) : cc+1
     If cc%1000=0:SetGadgetState(3, cc):EndIf
   Wend 
EndProcedure 

Procedure Swap24_POINT_PLOT(img) 
  SetGadgetState(3,0) : cc=0
  StartDrawing(ImageOutput(img))
    For j=0 To ImageHeight(img)-1
      For i=0 To ImageWidth(img)-1
        color = Point(i,j)
        Plot(i,j, RGB(Blue(color),Green(color),Red(color)))
        cc+1
        If cc%1000=0:SetGadgetState(3, cc):EndIf
      Next
    Next
  StopDrawing()
EndProcedure 
BERESHEIT
abarkley
User
User
Posts: 10
Joined: Sun Jun 07, 2009 7:44 pm
Location: London, UK

Post by abarkley »

Thanks for that. A bit complex for this noob - useful for me to try to work through it though.

Can I rephrase the question?

Is it realistic for me to work on a bitmap in memory without making any operating system calls? You say that the native PB commands are pretty quick.

The app is fairly simple - sort of very limited Photoshop - and I'm thinking about it running on a basic netbook (altho, I know zip about Linux at the moment).
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8453
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

My example employs only one API call, GetObject_(), used to get the address of the color bits. Surely you can live with that?
BERESHEIT
coder14
Enthusiast
Enthusiast
Posts: 327
Joined: Tue Jun 21, 2011 10:39 am

Re:

Post by coder14 »

idle wrote:

Code: Select all

 Procedure CopyImageToMemory(ImageNumber, Memory)
 
  Protected TemporaryDC, TemporaryBitmap.BITMAP, TemporaryBitmapInfo.BITMAPINFO
 
  TemporaryDC = CreateDC_("DISPLAY", #Null, #Null, #Null)
 
  GetObject_(ImageID(ImageNumber), SizeOf(BITMAP), TemporaryBitmap.BITMAP)
  
   
  TemporaryBitmapInfo\bmiHeader\biSize        = SizeOf(BITMAPINFOHEADER)
  TemporaryBitmapInfo\bmiHeader\biWidth       = TemporaryBitmap\bmWidth
  TemporaryBitmapInfo\bmiHeader\biHeight      = -TemporaryBitmap\bmHeight
  TemporaryBitmapInfo\bmiHeader\biPlanes      = 1
  TemporaryBitmapInfo\bmiHeader\biBitCount    = 32
  TemporaryBitmapInfo\bmiHeader\biCompression = #BI_RGB
 
  GetDIBits_(TemporaryDC, ImageID(ImageNumber), 0, TemporaryBitmap\bmHeight, Memory, TemporaryBitmapInfo, #DIB_RGB_COLORS)
 
  DeleteDC_(TemporaryDC)
 
EndProcedure 

Procedure CopyMemoryToImage(Memory, ImageNumber)
 
  Protected TemporaryDC, TemporaryBitmap.BITMAP, TemporaryBitmapInfo.BITMAPINFO
 
  TemporaryDC = CreateDC_("DISPLAY", #Null, #Null, #Null)
 
  GetObject_(ImageID(ImageNumber), SizeOf(BITMAP), TemporaryBitmap.BITMAP)
 
  TemporaryBitmapInfo\bmiHeader\biSize        = SizeOf(BITMAPINFOHEADER)
  TemporaryBitmapInfo\bmiHeader\biWidth       = TemporaryBitmap\bmWidth
  TemporaryBitmapInfo\bmiHeader\biHeight      = -TemporaryBitmap\bmHeight
  TemporaryBitmapInfo\bmiHeader\biPlanes      = 1
  TemporaryBitmapInfo\bmiHeader\biBitCount    = 32
  TemporaryBitmapInfo\bmiHeader\biCompression = #BI_RGB
 
  SetDIBits_(TemporaryDC, ImageID(ImageNumber), 0, TemporaryBitmap\bmHeight, Memory, TemporaryBitmapInfo, #DIB_RGB_COLORS)
 
  DeleteDC_(TemporaryDC)
 
EndProcedure
Sorry to bump an old topic but is there any way to convert these two functions for Mac OSX? :?:
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: Work on image in memory

Post by Keya »

here is an example of reading every pixel in an image, in memory, no Point()/Plot(), all OS:

Code: Select all

Structure RGB
  r.a
  g.a
  b.a
EndStructure

Procedure ReadImage(hImg)
  Protected *imgbuf, *pixel.RGB, Pixbytes, Rowbytes, x,y, width, height
  If StartDrawing(ImageOutput(hImg))
    width = ImageWidth(hImg)
    height = ImageHeight(hImg)
    Pixbytes = ImageDepth(hImg)/8
    Rowbytes = DrawingBufferPitch()
    *imgbuf = DrawingBuffer()
    For y = 0 To height-1
      *pixel = *imgbuf + (y * Rowbytes)
      For x = 0 To width-1      
        Debug "RGB = " + Hex(*pixel\r)+" "+Hex(*pixel\g)+" "+Hex(*pixel\b)  ;RGB on Linux/Mac, BGR on Windows      
        *pixel + Pixbytes
      Next x
    Next y    
    StopDrawing()  
  EndIf
EndProcedure

UsePNGImageDecoder(): UseJPEGImageDecoder()
Define hImg = LoadImage(#PB_Any,"c:\test.jpg")
If hImg = 0: MessageRequester("Error","Couldnt load image"): End: EndIf
ReadImage(hImg)
coder14
Enthusiast
Enthusiast
Posts: 327
Joined: Tue Jun 21, 2011 10:39 am

Re: Work on image in memory

Post by coder14 »

Keya wrote:here is an example of reading every pixel in an image, in memory, no Point()/Plot(), all OS:

Code: Select all

Structure RGB
  r.a
  g.a
  b.a
EndStructure

Procedure ReadImage(hImg)
  Protected *imgbuf, *pixel.RGB, Pixbytes, Rowbytes, x,y, width, height
  If StartDrawing(ImageOutput(hImg))
    width = ImageWidth(hImg)
    height = ImageHeight(hImg)
    Pixbytes = ImageDepth(hImg)/8
    Rowbytes = DrawingBufferPitch()
    *imgbuf = DrawingBuffer()
    For y = 0 To height-1
      *pixel = *imgbuf + (y * Rowbytes)
      For x = 0 To width-1      
        Debug "RGB = " + Hex(*pixel\r)+" "+Hex(*pixel\g)+" "+Hex(*pixel\b)  ;RGB on Linux/Mac, BGR on Windows      
        *pixel + Pixbytes
      Next x
    Next y    
    StopDrawing()  
  EndIf
EndProcedure

UsePNGImageDecoder(): UseJPEGImageDecoder()
Define hImg = LoadImage(#PB_Any,"c:\test.jpg")
If hImg = 0: MessageRequester("Error","Couldnt load image"): End: EndIf
ReadImage(hImg)
Which function is that? :?
Post Reply