Jump to content

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


Go to solution Solved by UEZ,

Recommended Posts

Posted

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?

Posted (edited)

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

  • Solution
Posted (edited)

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted

@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.

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
  • Recently Browsing   0 members

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