Copy imageID to *mem (is this the proper/best way?)

Just starting out? Need help? Post your questions and find answers here.
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Copy imageID to *mem (is this the proper/best way?)

Post by jassing »

(runnable code at end)

I have a need to draw an image, then copy that image to a memory address. What I came up with works, but i don't do enough with images to be sure it's the best (or proper) way to do it.
Snippet, non runnable, just to show the code I am concerned with being a best-method

Code: Select all

    hImage = CreateImage( #PB_Any, nWidth, nHeight, 32 )
    If IsImage(hImage)
      If StartDrawing( ImageOutput( hImage ) )
        DrawImage( ... )
        
        ;- try to copy image to a memory address.
        Protected nImageSize = DrawingBufferPitch() * ImageHeight( hImage ),
                  *imageBuffer = DrawingBuffer(),
                  nHeaderSize = ?endbmpheader-?bmpHeader
        *mem = AllocateMemory( nImageSize + nHeaderSize )
        CopyMemory( ?bmpHeader, *mem, nHeaderSize )
        CopyMemory( *imageBuffer, *mem + nHeaderSize, nImageSize )
        FreeImage( hImage )
      EndIf           
      StopDrawing()
    EndIf
Actual code that can be executed.

Code: Select all

EnableExplicit
Procedure CaptureScreen_( nLeft, nTop, nWidth, nHeight )
  Protected dcSource = CreateDC_( @"DISPLAY", #Null, #Null, #Null )
  
  If dcSource  <> #Null
    Protected dcDestination = CreateCompatibleDC_( dcSource )
    
    If dcDestination <> #Null
      Protected hCapturedImage = CreateCompatibleBitmap_( dcSource, nWidth, nHeight )
      
      If hCapturedImage <> #Null
        SelectObject_( dcDestination, hCapturedImage )
        BitBlt_( dcDestination, 0, 0, nWidth, nHeight, dcSource, 0, 0, #SRCCOPY )
      EndIf
      DeleteDC_( dcDestination )
    EndIf
    DeleteDC_( dcSource )
  EndIf
  ProcedureReturn hCapturedImage
EndProcedure

Procedure CaptureScreenToMemory()
  Protected nWidth    = GetSystemMetrics_( #SM_CXSCREEN ),
            nHeight   = GetSystemMetrics_( #SM_CYSCREEN ),
            hCapturedImage  = CaptureScreen_( 0, 0,    nWidth, nHeight ),
            hImage, *mem
  
  If hCapturedImage
    hImage = CreateImage( #PB_Any, nWidth, nHeight, 32 )
    If IsImage(hImage)
      If StartDrawing( ImageOutput( hImage ) )
        DrawImage( hCapturedImage, 0, 0 )
        
        ;- try to copy image to a memory address.
        Protected nImageSize = DrawingBufferPitch() * ImageHeight( hImage ),
                  *imageBuffer = DrawingBuffer(),
                  nHeaderSize = ?endbmpheader-?bmpHeader
        *mem = AllocateMemory( nImageSize + nHeaderSize )
        CopyMemory( ?bmpHeader, *mem, nHeaderSize )
        CopyMemory( *imageBuffer, *mem + nHeaderSize, nImageSize )
        FreeImage(hImage)
      EndIf           
      StopDrawing()
    EndIf
    DeleteObject_(hCapturedImage)
  EndIf 
  ProcedureReturn *mem
EndProcedure

Define *mem = CaptureScreenToMemory()
CreateFile( 0, "c:\temp\test3.bmp" )
WriteData( 0, *mem, MemorySize( *mem ) )
CloseFile( 0 ) 

DataSection
  bmpHeader:
  Data.b $42, $4d, $36, $08, $40, $00, $00, $00, $00, $00, $36, $00, $00, $00, $28, $00
  Data.b $00, $00, $56, $05, $00, $00, $00, $03, $00, $00, $01, $00, $20, $00, $00, $00
  Data.b $00, $00, $00, $08, $40, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
  Data.b $00, $00, $00, $00, $00, $00
  endbmpheader:
EndDataSection
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Copy imageID to *mem (is this the proper/best way?)

Post by idle »

Code: Select all

Procedure CopyImageToMemory(ImageNumber, Memory)
 
  Protected TemporaryDC.L, 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.L, 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


jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Copy imageID to *mem (is this the proper/best way?)

Post by jassing »

Thanks idle.

Why is your code better? I'm asking to understand, not to be flippant or anything. Faster? No "header" bs?

Thank you.
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Copy imageID to *mem (is this the proper/best way?)

Post by idle »

Its just what I've used in the past, SetDIBits and GetDiBits used to be faster and also handled bit depth conversion if I recall.
infratec
Always Here
Always Here
Posts: 7583
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Copy imageID to *mem (is this the proper/best way?)

Post by infratec »

Code: Select all

EncodeImage()
:?:
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Copy imageID to *mem (is this the proper/best way?)

Post by jassing »

idle wrote: Tue Apr 30, 2024 3:29 am Its just what I've used in the past, SetDIBits and GetDiBits used to be faster and also handled bit depth conversion if I recall.
Fair.. Thank you.
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Copy imageID to *mem (is this the proper/best way?)

Post by jassing »

infratec wrote: Tue Apr 30, 2024 9:25 am

Code: Select all

EncodeImage()
:?:
oooohhhhh!! Thank you!
Post Reply