Sign in to follow this  
Followers 0
S0789300

GDI + Positioning of Lines/Rects

14 posts in this topic

#1 ·  Posted (edited)

I am attempting to use GDI methods in Autoit to modify a partial screenshot to at minimum add a 25 pixel black frame around the partial image, and perhaps draw over the 1-2 pixel gray lines with black ones, making a black box (the black areas in the preview image cannot be overdrawn as a list will be filling it). I have attempted a basic GDI fill rectangle, but cannot even get it to draw anything over the captured gif. Any help would be greatly appreciated.

Here is the basic GDI stuff I wrote quickly but couldn't get it to draw anything. The code doesn't crash or throw an exception - it simply doesn't draw.

$sFileName = "D:\My OCR\Partial.gif"
    _GDIPlus_Startup ()
    
    Local $hGraphics
    
    $hImage = _GDIPlus_ImageLoadFromFile("D:\My OCR\Partial.gif") ; creates the GDI object
    
    
    $hPen = _GDIPlus_PenCreate ()
    _GDIPlus_PenSetWidth($hPen, 15)
    
    $iX = _GDIPlus_ImageGetWidth ($hImage)
    $iY = _GDIPlus_ImageGetHeight ($hImage)
    
    ;$hImage2 = _GDIPlus_BitmapCreateFromHBITMAP ($hImage)
    
    $hGraphics = _GDIPlus_ImageGetGraphicsContext ($hImage)
    ;_GDIPlus_GraphicsDrawImage ($hGraphics, $hImage2, 100, 100)
    
    ;_GDIPlus_GraphicsDrawRect ($hGraphics, 5, 25, 50, 50, $hPen)
    
    _GDIPlus_GraphicsFillRect($hImage, 10, 10, 50, 50)

    
    _GDIPlus_ImageSaveToFile($hImage, $sFileName)
    
    _GDIPlus_ImageDispose ($hImage)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_ShutDown ()
Edited by S0789300

Share this post


Link to post
Share on other sites



Hi mate

I'm a noob and have never used this func before so take my post with a pinch of salt.

I notice you are using the filename instead of the handle of the file to define your image, in the help example, it using the handle of the image rather than the filename.

Just wondering if that may be your problem.


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

The image there is not something GDI has drawn on. I have just taken a screenshot and removed the list text in it in photoshop. It is there to show what I want to cover over with GDI.

Share this post


Link to post
Share on other sites

On second thoughts, looking at the thumbnail, it seems it is drawing a rectangle over your image, when infact you want to paste your image into the rectangle.

And no, I want to draw rectangles around the image to create a frame, and draw lines to cover up the gray lines.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Hi. I gather the op is using XP? if so then GDI+ has issues under xp when working with images less the 24bpp.

Gif files are less then 24bpp, also color indexed BMP files are less then 24bpp.

You can easily work around the issue

#include <GDIPlus.au3>

Global $sRegPath, $sImageIn, $sImageOut

$sRegPath = "HKLM\SOFTWARE\AutoIt v3\AutoIt"
If StringInStr("X64IA64", @OSArch) Then $sRegPath = StringReplace($sRegPath, "SOFTWARE", "SOFTWARE\Wow6432Node")

$sImageIn = RegRead($sRegPath, "InstallDir") & "\Examples\GUI\logo4.gif"
$sImageOut = @ScriptDir & "\Partial.gif"


Local $hImage, $aRet, $hBmp, $hBitmap, $hGraphic, $hPen

_GDIPlus_Startup()

$hImage = _GDIPlus_ImageLoadFromFile($sImageIn)
$iW = _GDIPlus_ImageGetWidth($hImage)
$iH = _GDIPlus_ImageGetHeight($hImage)

;~ ; XP has an issue when drawing on a loaded image that is less the 24bpp
;~ ; Gif files have less the 24bpp color, Indexed Bmp are also less the 24bpp
;~ ; So we do a check, and craete a new image that we can draw on if the loaded image is less then 24bpp.
$aRet = _GDIPlus_ImageGetPixelFormat($hImage)
If Int(StringRegExpReplace($aRet[1], "\D+", "")) < 24 Then
    $hBmp = _WinAPI_CreateBitmap($iW, $iH, 1, 32)
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBmp)
    _WinAPI_DeleteObject($hBmp)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsDrawImage($hGraphic, $hImage, 0, 0)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_ImageDispose($hImage)
    $hImage = _GDIPlus_BitmapCloneArea($hBitmap, 0, 0, $iW, $iH, $GDIP_PXF32ARGB)
    _GDIPlus_BitmapDispose($hBitmap)
EndIf

;Now we have a drawable image lets create a red pen and draw a rect around the outside of the image
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
$hPen = _GDIPlus_PenCreate(0xFFFF0000, 4)
_GDIPlus_GraphicsDrawRect($hGraphic, 2, 2, $iW - 4, $iH - 4, $hPen)
_GDIPlus_PenDispose($hPen)
_GDIPlus_GraphicsDispose($hGraphic)

_GDIPlus_ImageSaveToFile($hImage, $sImageOut)
_GDIPlus_ImageDispose($hImage)

_GDIPlus_Shutdown()

If FileExists($sImageOut) Then ShellExecute($sImageOut)
Edited by smashly

Share this post


Link to post
Share on other sites

@Smashy - thanks it sort of works, but the output other than the red line, is really really fuzzy. I am assuming this is because it is less than 24bpp and the bmp redraw fuzzies it out. What format do you recommend I be saving the screenshot in if .gif is not good enough? I think I can do .jpeg, .png and tiff perhaps without messing with my scripting too much.

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Actually, I tested in .jpeg and it seems to do a lot better. Would .png or tiff increase quality more?

Edited by S0789300

Share this post


Link to post
Share on other sites

Also - is there a way to add a frame with GDI around an image thats larger than the original pixel dimensions of that image? IE: increase the ruler size of the image, but solely for the purpose of adding a black frame around it (to push a list more towards the center of the image)

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

PNG would be a good format to load/save your image as, tif is good but it's not really size friendly when dealing with large images...

Jpg is not that good either due to the quality loss under compression.

#include <GDIPlus.au3>

Global $sRegPath, $sImageIn, $sImageOut

$sRegPath = "HKLM\SOFTWARE\AutoIt v3\AutoIt"
If StringInStr("X64IA64", @OSArch) Then $sRegPath = StringReplace($sRegPath, "SOFTWARE", "SOFTWARE\Wow6432Node")

$sImageIn = RegRead($sRegPath, "InstallDir") & "\Examples\GUI\logo4.gif"
$sImageOut = @ScriptDir & "\Partial.png"


Local $hImage, $aRet, $hBmp, $hBitmap, $hGraphic, $hPen

_GDIPlus_Startup()

$hImage = _GDIPlus_ImageLoadFromFile($sImageIn)
$iW = _GDIPlus_ImageGetWidth($hImage)
$iH = _GDIPlus_ImageGetHeight($hImage)

;~ ; XP has an issue when drawing on a loaded image that is less the 24bpp
;~ ; Gif files have less the 24bpp color, Indexed Bmp are also less the 24bpp
;~ ; So we do a check, and craete a new image that we can draw on if the loaded image is less then 24bpp.
$aRet = _GDIPlus_ImageGetPixelFormat($hImage)
If Int(StringRegExpReplace($aRet[1], "\D+", "")) < 24 Then
    $hBmp = _WinAPI_CreateBitmap($iW, $iW, 1, 32) ;Make this as big as you need.. 
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBmp) ;This is the image your drawing your loaded image on to.
    _WinAPI_DeleteObject($hBmp)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsClear($hGraphic, 0xFFFF0000); setting the new image background to red.
    _GDIPlus_GraphicsDrawImage($hGraphic, $hImage, 0, ($iW-$iH)/2); your drawing your loaded image on to the new image.
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_ImageDispose($hImage)
    $hImage = $hBitmap
EndIf


_GDIPlus_ImageSaveToFile($hImage, $sImageOut)
_GDIPlus_ImageDispose($hImage)

_GDIPlus_Shutdown()

If FileExists($sImageOut) Then ShellExecute($sImageOut)

Cheers

Edited by smashly

Share this post


Link to post
Share on other sites

Ok, ill try .png. I need to make a big black frame to force my list into the center. It would also increase my accuracy if I could write with a black pen over those gray lines (black meaning, match the background).

Share this post


Link to post
Share on other sites

Is there a quick command to switch to grayscale via GDI?

Share this post


Link to post
Share on other sites

Yes, it seems SIAO made some headway with the GDI to greyscale. Now all I need to do is figure out how to correctly implement the code snipped above to 'frame' the image correctly so that my text is forced into the middle.

Share this post


Link to post
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
Sign in to follow this  
Followers 0