Jump to content

Placing image data created from scratch in GDIplus onto the Windows clipboard


Go to solution Solved by UEZ,

Recommended Posts

I have been searching through the help files and any posts I can find related to the clipboard to no avail.

I am creating a blank image from scratch in GDIplus, then drawing the image from within my script.  I am trying to place the resulting image onto the windows clipboard.  It seems to work like a charm if the image started out on the clipboard, as a file, or as a screen capture, but just refuses to work when I create from scratch.

To be more specific, I promised ages ago that I would update my barcode UDFs to optionally place the barcode image on the clipboard.  Do date, I have been unable to do so.  The image creation is straightforward.  Here is an excerpt from my Code128 UDF.

_GDIPlus_Startup()
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0((StringLen($vBarcodeObj[5]) + 14) * $vBarcodeObj[1], $vBarcodeObj[4] + $iFontMargin, $GDIP_PXF01INDEXED)
    __Bcode128_BitmapSetResolution($hBitmap, $vBarcodeObj[3], $vBarcodeObj[3])
    Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxt, 0)
    _GDIPlus_GraphicsClear($hBmpCtxt, 0xFFFFFFFF)

At this point, I am able to draw the bars and text as needed.  Then the trouble begins.

_ClipBoard_Open(0)
    _ClipBoard_SetDataEx($hBitmap, $CF_BITMAP)
    _ClipBoard_Close()

Applications recognize that something is on the clipboard, but when I attempt to paste it into a graphics editor, I get an error that the clipboard does not contain valid graphic data.

I am sure there is a step missing somewhere between my creating the image and it being ready to place on the clipboard, but I have not been able to figure it out.  Any suggestions?

Link to comment
Share on other sites

if that help

 

Edit:
after taking a look at your UDF  (nice job by the way)
my approach to  adaptation 

...
...

#include <GDIPlus.au3>
#include "StringSize.au3"; by Melba23 - http://www.autoitscript.com/forum/topic/114034-stringsize-m23-new-version-16-aug-11/
#include <File.au3>
#include <Clipboard.au3>

; #FUNCTION# ====================================================================================================================
; Name ..........: _Bcode128_GenCode
; Description ...: Creates a Code128A/B/C optimized barcode from supplied data
; Syntax ........: _Bcode128_GenCode($sData[, $sOutFile = Default[, $iDPI = Default[, $fMinBar = Default[, $fBarHeight = Default[,
;                  $iPrintText = Default]]]]])
; Parameters ....: $sData               - A string value to encode into a Code128 barcode
;                  $sOutFile            - [optional] Where to write out the BMP file. Default is to create a random temp file
;                                         0 = Copy to the clipboard (planned, but not yet implemented)
;                                         1 = Create a randomly named temp file (Default)
;                                         String = Write to specified path\filename (assumes valid path and filename)
;                  $iDPI                - [optional] The dots-per-inch setting for the BMP file.  Default is 96
;                  $fMinBar             - [optional] Width of the narrowest bar, in inches (0.01 is the recommended standard for
;                                         most handheld scanners). Default is 0.01 inches
;                  $fBarHeight          - [optional] The height of the barcode, in inches (15% of the width or 0.5 inches
;                                         ,whichever is larger, is the standard according to the GS1-128 specification). Default
;                                         is to automatically calculate according to this standard.
;                  $iPrintText          - [optional] Whether to print the data string under the barcode. Default is True.
; Return values .: String containing the location and name of the BMP file created, or "" if copied to the clipboard.
; Author ........: David E Williams (willichan)
; Modified ......:
; Remarks .......: Invalid characters in $sData will be skipped rather than generating an error
;                  Copying to the clipboard is not yet implemented.  Random temp file will be made instead.
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _Bcode128_GenCode($sData, $sOutFile = Default, $iDPI = Default, $fMinBar = Default, $fBarHeight = Default, $iPrintText = Default)
    Local $vBarcodeObj[6], $t
    If IsNumber($sOutFile) Then $sOutFile = 1 ;;; *** treat any number like a temp file, in case the user messed up ***
    If ($sOutFile = Default) Or ($sOutFile = 1) Or ($sOutFile = 0) Then $sOutFile = _TempFile(@TempDir, "~", ".bmp", 7)
    If $iPrintText = Default Then $iPrintText = True ;print text at bottom of barcode
    If $iDPI = Default Then $iDPI = 96 ;Dots Per Inch used for the image file
    If $fMinBar = Default Then $fMinBar = 0.01 ;Minimum bar width in Inches
    Local $iModWidth = Ceiling($iDPI * $fMinBar) ;Number of Dots per Minimum Bar
    $t = __Bcode128_EncodeData($sData)
    If $iPrintText Then
        $vBarcodeObj[0] = $t[1] ;encoded text
    Else
        $vBarcodeObj[0] = ""
    EndIf
    $vBarcodeObj[5] = $t[0] ;bar encoding
    $vBarcodeObj[1] = $iModWidth
    $vBarcodeObj[2] = $sOutFile
    $vBarcodeObj[3] = $iDPI
    If $fBarHeight = Default Then
        $fBarHeight = ((StringLen($vBarcodeObj[5]) * $iModWidth) / $iDPI) * 0.15
        If $fBarHeight < 0.5 Then $fBarHeight = 0.5
        $fBarHeight = Ceiling($iDPI * $fBarHeight)
    EndIf
    $vBarcodeObj[4] = $fBarHeight
    __Bcode128_CreateImage($vBarcodeObj)
    If ($sOutFile = 0) Then
        __Bcode128_PicToClip($sOutFile)
        FileDelete($sOutFile)
    EndIf

EndFunc   ;==>_Bcode128_GenCode
...
...

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name ..........: __Bcode128_PicToClip
; Description ...: put image from $sPath to clipboard
; Syntax ........: __Bcode128_PicToClip($sPath)
; Parameters ....: $sPath
; Return values .: None
; Author ........: Nine
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........: https://www.autoitscript.com/forum/topic/209954-how-to-put-image-to-clipboard-from-file/#comment-1515671
; Example .......: No
; ===============================================================================================================================
Func __Bcode128_PicToClip($sPath)
    _GDIPlus_Startup()
    Local $hImage = _GDIPlus_ImageLoadFromFile($sPath)
    Local $hBitmap1 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    _GDIPlus_ImageDispose($hImage)
    Local $hBitmap2 = _WinAPI_CopyImage($hBitmap1, $IMAGE_BITMAP, 0, 0, $LR_COPYDELETEORG + $LR_COPYRETURNORG)
    _WinAPI_DeleteObject($hBitmap1)
    _GDIPlus_Shutdown()
    _ClipBoard_Open(0)
    _ClipBoard_Empty()
    _ClipBoard_SetDataEx($hBitmap2, $CF_BITMAP)
    _ClipBoard_Close()
    _WinAPI_DeleteObject($hBitmap2)
EndFunc   ;==>PicToClip

 

Edited by ioa747
Edit

I know that I know nothing

Link to comment
Share on other sites

  • Solution

You must first convert the GDI+ image to a GDI clipboard bitmap format using _WinAPI_CopyImage function.

#include <GDIPlus.au3>
#include <Clipboard.au3>

Example()

Func Example()
        _GDIPlus_Startup()
        Local Const $iW = 460, $iH = 100
        Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH, $GDIP_PXF01INDEXED) ;create an empty bitmap
        Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap) ;get the graphics context of the bitmap
        _GDIPlus_GraphicsClear($hBmpCtxt, 0xFFFFFFFF) ;clear bitmap with color white
        _GDIPlus_GraphicsDrawString($hBmpCtxt, "AutoIt rulez!", 0, 0, "Comic Sans MS", 52) ;draw some text to the bitmap

        Local $hBitmapGDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        Local $hClipboard_Bitmap = _WinAPI_CopyImage($hBitmapGDI, 0, 0, 0, BitOR($LR_COPYDELETEORG, $LR_COPYRETURNORG, $LR_MONOCHROME))
        _ClipBoard_Open(0)
        _ClipBoard_SetDataEx($hClipboard_Bitmap, $CF_BITMAP)
        _ClipBoard_Close()
        _WinAPI_DeleteObject($hBitmapGDI)
        _WinAPI_DeleteObject($hClipboard_Bitmap)

        ;cleanup GDI+ resources
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        _GDIPlus_Shutdown()
EndFunc   ;==>Example

 

Edited by UEZ
added $LR_MONOCHROME

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

@ioa747  Thank you for your feedback and solution.  If I could not go directly to clipboard, that would have been the solution for me to take.

 

@UEZ  That worked exactly as needed.  I had looked at your similar solution in another of your posts, but I must have missed the _GDIPlus_BitmapCreateHBITMAPFromBitmap step in there.

 

I can start updating my UDFs with the clipboard feature now.  Thanks again.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...