Page 1 of 1

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

Posted: Sat Apr 27, 2024 4:52 pm
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

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

Posted: Mon Apr 29, 2024 9:07 pm
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



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

Posted: Tue Apr 30, 2024 12:02 am
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.

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

Posted: Tue Apr 30, 2024 3:29 am
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.

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

Posted: Tue Apr 30, 2024 9:25 am
by infratec

Code: Select all

EncodeImage()
:?:

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

Posted: Sat May 11, 2024 1:19 am
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.

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

Posted: Sat May 11, 2024 1:20 am
by jassing
infratec wrote: Tue Apr 30, 2024 9:25 am

Code: Select all

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