Sign in to follow this  
Followers 0
willichan

Changing the DPI of a BMP

4 posts in this topic

I am trying to set the DPI of a BMP file (not resizing).  The program that generated the BMP sets it to 96, and has no options to set it otherwise.

The client requires that this be set to 120 (go figure).  I can manually set it using an image editor, but there are more than 1000 images, so I was hoping to do this with a script. 

I found UEZ's solution () and have tried to modify it to work with the current GDIPlus, but have not been successful.  The resulting image created is identical to the original, including the DPI setting of 96.

Any suggestions?

#include <file.au3>
#include <GDIPlus.au3>

__FixResolution("c:\TestBmp.bmp", 120)


Func __FixResolution($sInpath, $iDPI)
    Local $hImage, $sOutpath, $aResult, $sCLSID
    $sOutpath = StringLeft($sInpath, StringLen($sInpath)-4) & "_" & $iDPI & ".bmp"
    _GDIPlus_Startup()
    $hImage = _GDIPlus_BitmapCreateFromFile($sInpath)
    $aResult = _GDIPlus_BitmapSetResolution($hImage, $iDPI, $iDPI)
    $sCLSID = _GDIPlus_EncodersGetCLSID("bmp")
    _GDIPlus_ImageSaveToFileEx($hImage, $sOutpath, $sCLSID, 0)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
EndFunc   ;==>__FixResolution

; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_BitmapSetResolution
; Description ...: Sets the resolution of this Bitmap object
; Syntax.........: _GDIPlus_BitmapSetResolution($hBitmap, $nDpiX, $nDpiY)
; Parameters ....: $hBitmap - Pointer to the Bitmap object
;   $nDpiX  - Value that specifies the horizontal resolution in dots per inch.
;   $nDpiX  - Value that specifies the vertical resolution in dots per inch.
; Return values .: Success  - True
;   Failure     - False and either:
;   |@error and @extended are set if DllCall failed
;   |$GDIP_STATUS contains a non zero value specifying the error code
; Remarks .......: None
; Related .......:
; Link ..........; @@MsdnLink@@ GdipBitmapSetResolution
; Example .......; Yes
; ===============================================================================================================================
Func _GDIPlus_BitmapSetResolution($hBitmap, $nDpiX, $nDpiY)
    Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipBitmapSetResolution", "hwnd", $hBitmap, "float", $nDpiX, "float", $nDpiY)

    If @error Then Return SetError(@error, @extended, False)
    $GDIP_STATUS = $aResult[0]
    Return $aResult[0] = 0
EndFunc ;==>_GDIPlus_BitmapSetResolution

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I goggled a bit and so I found out, that this is an error in Win7 and should work as expected in Win8 again.
Here is a workaround for Win7:

#include <File.au3>
#include <GDIPlus.au3>

Global $aBmp = _FileListToArray(@ScriptDir, "*.bmp", 1)

_GDIPlus_Startup()
For $i = 1 To $aBmp[0]
    __FixResolution($aBmp[$i], 120)
Next
_GDIPlus_Shutdown()


Func __FixResolution($sInpath, $iDPI)
    Local $hBitmapOrig, $hGDI, $hBitmap, $sOutpath, $iResult, $sCLSID
    $sOutpath = StringLeft($sInpath, StringLen($sInpath)-4) & "_" & $iDPI & ".bmp"
    $hBitmapOrig = _GDIPlus_BitmapCreateFromFile($sInpath)
    $hGDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmapOrig)
    _GDIPlus_BitmapDispose($hBitmapOrig)
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hGDI)
    _WinAPI_DeleteObject($hGDI)
    $iResult = _GDIPlus_BitmapSetResolution($hBitmap, $iDPI, $iDPI)
    $sCLSID = _GDIPlus_EncodersGetCLSID("bmp")
    _GDIPlus_ImageSaveToFileEx($hBitmap, $sOutpath, $sCLSID, 0)
    _GDIPlus_BitmapDispose($hBitmap)
EndFunc   ;==>__FixResolution

; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_BitmapSetResolution
; Description ...: Sets the resolution of this Bitmap object
; Syntax.........: _GDIPlus_BitmapSetResolution($hBitmap, $nDpiX, $nDpiY)
; Parameters ....: $hBitmap - Pointer to the Bitmap object
;   $nDpiX  - Value that specifies the horizontal resolution in dots per inch.
;   $nDpiX  - Value that specifies the vertical resolution in dots per inch.
; Return values .: Success  - True
;   Failure     - False and either:
;   |@error and @extended are set if DllCall failed
;   |$GDIP_STATUS contains a non zero value specifying the error code
; Remarks .......: None
; Related .......:
; Link ..........; @@MsdnLink@@ GdipBitmapSetResolution
; Example .......; Yes
; ===============================================================================================================================
Func _GDIPlus_BitmapSetResolution($hBitmap, $nDpiX, $nDpiY)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipBitmapSetResolution", "handle", $hBitmap, "float", $nDpiX, "float", $nDpiY)
    If @error Then Return SetError(@error, @extended, False)
    $GDIP_STATUS = $aResult[0]
    Return $aResult[0] = 0
EndFunc ;==>_GDIPlus_BitmapSetResolution

 

Edited by funkey

Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Share this post


Link to post
Share on other sites

Thanks!  That worked perfectly.

Glad to hear! You are welcome.


Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

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