Jump to content

GDI+ C/C++ Code to AutoIt Conversion


UEZ
 Share

Recommended Posts

jchd asked about a way to and I looked around at MSN and found this code here:

VOID Example_ConvertFormat(HDC hdc)
{
   Graphics graphics(hdc);
   Bitmap myBitmap(L"Photo.jpg");
   INT width = myBitmap.GetWidth();
   INT height = myBitmap.GetHeight();

   graphics.DrawImage(&myBitmap, 20, 20, width, height);

   // PaletteTypeFixedHalftone27 has 36 entries. A ColorPalette structure has
   // room for one entry, so space is allocated for an additional 35 entries.
   ColorPalette* pal = (ColorPalette*)malloc(sizeof(ColorPalette) + 35*sizeof(ARGB));
   pal->Count = 36;
   pal->Flags = 0;

   Bitmap::InitializePalette(pal, PaletteTypeFixedHalftone27, 0, TRUE, NULL); 

   myBitmap.ConvertFormat(
      PixelFormat8bppIndexed,
      DitherTypeOrdered8x8,
      PaletteTypeFixedHalftone27,
      pal,
      0);

   graphics.DrawImage(&myBitmap, width + 40, 20, width, height);

   free(pal);
}

What I did so far is this code here due to my lack of C/C++ knowledge:

#include <array.au3>
#include <screencapture.au3>
#include <gdip.au3>

Global Const $GDIP_PXF32CMYK = 0x0000200F
Global Const $GDIP_PXFMAX = 0x00000010

Global Enum $DitherTypeNone = 0, $DitherTypeSolid, $DitherTypeOrdered4x4, $DitherTypeOrdered8x8, $DitherTypeOrdered16x16, $DitherTypeOrdered91x91, $DitherTypeSpiral4x4, $DitherTypeSpiral8x8, $DitherTypeDualSpiral4x4, $DitherTypeDualSpiral8x8, $DitherTypeErrorDiffusion
Global Enum $PaletteTypeCustom = 0, $PaletteTypeOptimal, $PaletteTypeFixedBW, $PaletteTypeFixedHalftone8, $PaletteTypeFixedHalftone27, $PaletteTypeFixedHalftone64, $PaletteTypeFixedHalftone125, $PaletteTypeFixedHalftone216, $PaletteTypeFixedHalftone252, $PaletteTypeFixedHalftone256

_GDIPlus_Startup()
$iW = 300
$iH = 300
$hHBitmap = _ScreenCapture_Capture("", 0, 0, $iW, $iH) ;24 bit screen capture
$hBitmap_screen = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap) ;convert bitmap format
$tPalette = _GDIPlus_ImageGetPalette($hBitmap_screen)
$pPalette = DllStructGetPtr($tPalette)
ConsoleWrite(_GDIPlus_BitmapConvertFormat($hBitmap_screen, $GDIP_PXF04INDEXED, $DitherTypeOrdered16x16, $PaletteTypeOptimal, $pPalette, 0) & "/" & @error & @LF)
_GDIPlus_ImageSaveToFile($hBitmap_screen, @ScriptDir & "Test.png")
_WinAPI_DeleteObject($hHBitmap)
_GDIPlus_BitmapDispose($hBitmap_screen)
_GDIPlus_Shutdown()
Exit

Func _GDIPlus_BitmapConvertFormat($hBitmap, $iPixelFormat, $iDitherType, $iPaletteType, $ptrPalette, $fAlphaThresholdPercent)
    Local $aResult = DllCall($ghGDIPDll, "bool", "GdipBitmapConvertFormat", "handle", $hBitmap, "long", $iPixelFormat, "long", $iPaletteType, "struct", $ptrPalette, "float", $fAlphaThresholdPercent)
    If @error Then Return SetError(@error, @extended, 0)
    Return 1
EndFunc

What I don't understand are these lines from above:

...
   // PaletteTypeFixedHalftone27 has 36 entries. A ColorPalette structure has
   // room for one entry, so space is allocated for an additional 35 entries.
   ColorPalette* pal = (ColorPalette*)malloc(sizeof(ColorPalette) + 35*sizeof(ARGB));
   pal->Count = 36;
   pal->Flags = 0;
...

When I run the autoit code I get the error code 5 back which means "InsufficientBuffer" and it seems to be that I've to convert also the lines above to autoit.

Can somebody help or point me to the right direction?

is needed!

Thanks,

UEZ

Edited by UEZ

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

Hi, do you mean something like that? I can't test since I currently have only Wine available and it does not implement GdipInitializePalette yet.

Edit: This function exists only in GDI+ 1.1 and later (Vista+), not available in XP.

#include <array.au3>
#include <screencapture.au3>
#include <scripts/gdip.au3>

Global Const $GDIP_PXF32CMYK = 0x0000200F
Global Const $GDIP_PXFMAX = 0x00000010

Global Enum $DitherTypeNone = 0, $DitherTypeSolid, $DitherTypeOrdered4x4, $DitherTypeOrdered8x8, $DitherTypeOrdered16x16, $DitherTypeOrdered91x91, $DitherTypeSpiral4x4, $DitherTypeSpiral8x8, $DitherTypeDualSpiral4x4, $DitherTypeDualSpiral8x8, $DitherTypeErrorDiffusion
Global Enum $PaletteTypeCustom = 0, $PaletteTypeOptimal, $PaletteTypeFixedBW, $PaletteTypeFixedHalftone8, $PaletteTypeFixedHalftone27, $PaletteTypeFixedHalftone64, $PaletteTypeFixedHalftone125, $PaletteTypeFixedHalftone216, $PaletteTypeFixedHalftone252, $PaletteTypeFixedHalftone256

_GDIPlus_Startup()
$iW = 300
$iH = 300
$hHBitmap = _ScreenCapture_Capture("", 0, 0, $iW, $iH) ;24 bit screen capture
$hBitmap_screen = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap) ;convert bitmap format
$tPalette = _GDIPlus_CreateColorPalette(36)
_GDIPlus_InitializePalette($tPalette, $PaletteTypeFixedHalftone27, 0, True, 0)
ConsoleWrite(_GDIPlus_BitmapConvertFormat($hBitmap_screen, $GDIP_PXF04INDEXED, $DitherTypeOrdered16x16, $PaletteTypeFixedHalftone27, $tPalette, 0) & "/err:" & @error & "/ext:" & @extended &  @LF)
_GDIPlus_ImageSaveToFile($hBitmap_screen, @ScriptDir & "Test.png")
_WinAPI_DeleteObject($hHBitmap)
_GDIPlus_BitmapDispose($hBitmap_screen)
_GDIPlus_Shutdown()
Exit

Func _GDIPlus_BitmapConvertFormat($hBitmap, $iPixelFormat, $iDitherType, $iPaletteType, $ptrPalette, $fAlphaThresholdPercent)
    Local $aResult = DllCall($ghGDIPDll, "bool", "GdipBitmapConvertFormat", "handle", $hBitmap, "long", $iPixelFormat, "long", $iDitherType, "long", $iPaletteType, "struct*", $ptrPalette, "float", $fAlphaThresholdPercent)
    If @error Then Return SetError(1, @error, 0)
    Return SetError($aResult[0], 0, Not $aResult[0])
EndFunc

Func _GDIPlus_CreateColorPalette($iEntries)
    If $iEntries < 1 Then Return SetError(1, 0, 0)
    Return DllStructCreate("uint Flags;uint Count;uint Entries[" & $iEntries & "];")
EndFunc

Func _GDIPlus_InitializePalette($tPalette, $iPaletteType, $iOptimalColors, $fUserTransparentColor, $pBitmap)
    Local $aResult = DllCall($ghGDIPDll, "long", "GdipInitializePalette", "struct*", $tPalette, "long", $iPaletteType, "int", $iOptimalColors, "bool", $fUserTransparentColor, "handle", $pBitmap)
    If @error Then Return SetError(1, @error, 0)
    Return SetError($aResult[0], 0, Not $aResult[0])
EndFunc
Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

The Test.png is empty (0 kb)

I will try to understand the differences from your modifications / additions and my code...

Br,

UEZ

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

I will try to understand the differences from your modifications / additions and my code...

I just added a missing parameter, fixed the type from struct to struct* and then added the two missing functions used in the C++ code.

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

These lines seems to be working to create a dithered 8bit (256 color) image:

#include <screencapture.au3>

If @OSBuild < 6000 Then Exit MsgBox(16, "Error", "GDI+ v1.1 needed -> Vista+ OS!", 10)

Global Const $GDIP_PXF32CMYK = 0x0000200F
Global Const $GDIP_PXFMAX = 0x00000010

Global Enum $DitherTypeNone = 0, $DitherTypeSolid, $DitherTypeOrdered4x4, $DitherTypeOrdered8x8, $DitherTypeOrdered16x16, $DitherTypeOrdered91x91, $DitherTypeSpiral4x4, $DitherTypeSpiral8x8, $DitherTypeDualSpiral4x4, $DitherTypeDualSpiral8x8, $DitherTypeErrorDiffusion
Global Enum $PaletteTypeCustom = 0, $PaletteTypeOptimal, $PaletteTypeFixedBW, $PaletteTypeFixedHalftone8, $PaletteTypeFixedHalftone27, $PaletteTypeFixedHalftone64, $PaletteTypeFixedHalftone125, $PaletteTypeFixedHalftone216, $PaletteTypeFixedHalftone252, $PaletteTypeFixedHalftone256

_GDIPlus_Startup()
$iW = 300
$iH = 300
$hHBitmap = _ScreenCapture_Capture("", 0, 0, $iW, $iH) ;24 bit screen capture
$hBitmap_screen = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap) ;convert bitmap format


$iColorCount = 36
$DitherType =  $DitherTypeOrdered8x8
$PaletteType = $PaletteTypeFixedHalftone27
$PixelFormat = $GDIP_PXF08INDEXED
$iColors = 2^8

$tPalette = DllStructCreate("uint Flags; uint Count; uint Entries[" & $iColorCount & "];")
$pPalette = DllStructGetPtr($tPalette)
DllStructSetData($tPalette, "Flags", $PaletteType)
DllStructSetData($tPalette, "Count", $iColorCount)

ConsoleWrite("> Init Palette: " & _GDIPlus_InitializePalette($pPalette, $PaletteType, $iColors, True, $hBitmap_screen) & @CRLF)
ConsoleWrite("! Error: " & @error & " Extended: " & @extended & @CRLF)

ConsoleWrite("> Convert: " & _GDIPlus_BitmapConvertFormat($hBitmap_screen, $PixelFormat, $DitherType, $PaletteType, $pPalette, 0) & @CRLF)
ConsoleWrite("! Error: " & @error & " Extended: " & @extended & @CRLF)

_GDIPlus_ImageSaveToFile($hBitmap_screen, @ScriptDir & "Test.png")
_WinAPI_DeleteObject($hHBitmap)
_GDIPlus_BitmapDispose($hBitmap_screen)
_GDIPlus_Shutdown()
ShellExecute(@ScriptDir & "Test.png")
Exit

Func _GDIPlus_BitmapConvertFormat($hBitmap, $iPixelFormat, $iDitherType, $iPaletteType, $ptrPalette, $falphaThresholdPercent)
    Local $aResult = DllCall($ghGDIPDll, "bool", "GdipBitmapConvertFormat", "handle", $hBitmap, "long", $iPixelFormat, "long", $iDitherType, "long", $iPaletteType, "struct*", $ptrPalette, "float", $falphaThresholdPercent)
    If @error Then Return SetError(@error, @extended, -1)
    Return $aResult[0]
EndFunc   ;==>_GDIPlus_BitmapConvertFormat


Func _GDIPlus_InitializePalette($pPalette, $iPaletteType, $iOptimalColors = 0, $bUseTransparentColor = True, $hBitmap = 0)
    Local $aResult = DllCall($ghGDIPDll, "bool", "GdipInitializePalette", "struct*", $pPalette, "long", $iPaletteType, "int", $iOptimalColors, "bool", $bUseTransparentColor, "handle", $hBitmap)
    If @error Then Return SetError(@error, @extended, -1)
    Return $aResult[0]
EndFunc   ;==>_GDIPlus_InitializePalette

Thanks to eukalyptus and progandy!

Tested on Win7 x64 + Aero!

Br,

UEZ

Edited by UEZ

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

Thanks to everyone.

Unfortunately this code produces errors on my test Vista x86 machine:

> Init Palette: -1

! Error: 0 Extended: 0

> Convert: -1

! Error: 0 Extended: 0

Anyway, the target will be XP, so no luck.

I"ll keep trying getting conversion to RGB555 output to TIFF or something. Else I'll stick to JPG if nothing works.

EDIT:

Tests show that there's actually no point at all this since JPG gives much smaller files!

test.jpg = 27 Kb (plain capture)

test.tiff = 84 Kb (32-bit TIFF LZW, for reference)

test565.tif = 62 Kb (RGB565 LZW)

test555.tif = 55 Kb (RGB555 LZW)

Thank you all for trying.

Edited by jchd

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Is this an alternative for you?

Code by eukalyptus! Thanks graphic god!

;coded by eukalyptus
#include <ScreenCapture.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>


$filename = @ScriptDir & "Test.png"
$bits = 4 ;1, 4, 8 only possible

$hHBitmap = _ScreenCapture_Capture("", 0, 0, 300, 300)
$hHBitmap2 = _Convert($hHBitmap, $bits)

$hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap2)

_ScreenCapture_SaveImage($filename, $hHBitmap2)

_WinAPI_DeleteObject($hHBitmap)
_WinAPI_DeleteObject($hHBitmap2)

ShellExecute($filename)

Exit

Func _Convert($hHBitmap, $iBPP) ;function by eukalyptus

    Local $tBitmap = DllStructCreate("long bmType; long bmWidth; long bmHeight; long bmWidthBytes; ushort bmPlanes; ushort bmBitsPixel; ptr bmBits;")
    DllCall('gdi32.dll', 'int', 'GetObject', 'int', $hHBitmap, 'int', DllStructGetSize($tBitmap), 'ptr', DllStructGetPtr($tBitmap))
    Local $iWidth = DllStructGetData($tBitmap, "bmWidth")
    Local $iHeight = DllStructGetData($tBitmap, "bmHeight")

    Switch $iBPP
        Case 1, 4, 8

        Case Else
            Return SetError(1, 1, False)
    EndSwitch


    Local $tBITMAPINFO = DllStructCreate("dword Size; long Width; long Height; word Planes; word BitCount; dword Compression; dword SizeImage; long XPelsPerMeter; long YPelsPerMeter; dword ClrUsed; dword ClrImportant; dword RGBQuad[256];")
    DllStructSetData($tBITMAPINFO, 'Size', 40)
    DllStructSetData($tBITMAPINFO, 'Width', $iWidth)
    DllStructSetData($tBITMAPINFO, 'Height', -$iHeight)
    DllStructSetData($tBITMAPINFO, 'Planes', 1)
    DllStructSetData($tBITMAPINFO, 'BitCount', $iBPP)

    Local $iColorCnt = BitShift(1, -$iBPP)

    DllStructSetData($tBITMAPINFO, 'ClrUsed', $iColorCnt)
    DllStructSetData($tBITMAPINFO, 'ClrImportant', $iColorCnt)

    Switch $iBPP
        Case 1
            DllStructSetData($tBITMAPINFO, 'RGBQuad', BitOR(BitShift(0xFF, -16), BitShift(0xFF, -8), 0xFF), 2)

        Case 4
            Local $aCol[16] = [8, 24, 38, 56, 72, 88, 104, 120, 136, 152, 168, 184, 210, 216, 232, 248]
            For $i = 0 To 15
                DllStructSetData($tBITMAPINFO, 'RGBQuad', BitOR(BitShift($aCol[$i], -16), BitShift($aCol[$i], -8), $aCol[$i]), $i + 1)
            Next

        Case 8
            For $i = 0 To $iColorCnt - 1
                DllStructSetData($tBITMAPINFO, 'RGBQuad', BitOR(BitShift($i, -16), BitShift($i, -8), $i), $i + 1)
            Next

    EndSwitch

    Local $hDCD = _WinAPI_CreateCompatibleDC(0)
    Local $hDCS = _WinAPI_CreateCompatibleDC($hDCD)
    Local $aRet = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBITMAPINFO), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'dword', 0)
    Local $hHBmp = $aRet[0]
    Local $hOrigD = _WinAPI_SelectObject($hDCD, $hHBmp)
    Local $hOrigS = _WinAPI_SelectObject($hDCS, $hHBitmap)

    _WinAPI_BitBlt($hDCD, 0, 0, $iWidth, $iHeight, $hDCS, 0, 0, $SRCCOPY)

    _WinAPI_SelectObject($hDCD, $hOrigD)
    _WinAPI_SelectObject($hDCS, $hOrigS)
    _WinAPI_DeleteDC($hDCD)
    _WinAPI_DeleteDC($hDCS)

    Return $hHBmp
EndFunc   ;==>_Convert

It will create a non dithered 4-bit greyscale image and save it in png format. File size is approx. 6kb for this resolution.

Should work also on WinXP!

Br,

UEZ

Edited by UEZ

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

Richard,

Yes I know JPG is lossy (at least most JPG formats) while TIFF isn't. But for my application it doesn't make any difference unless JPG quality is set overly low.

UEZ,

Thank you and eukalyptus for the effort. The code currently does nothing on this Vista x86 machine (no file created). I'll look later what's going on.

I had seen the use of CreateDIBSection and Bitblt in a few C# examples on the web, but didn't get it right converting to AutoIt.

Geez, I may be expecting too much, but I don't understand that what I consider an elementary operation should require deep and cutting-edge knowledge of that many Windows graphics primitives mixing DC, DDB, DIB, and much more. I'm not complaining, just perplex.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

I accidentally posted a modified code which doesn't create a greyscaled image (ouch)! -> edited!

Code tested on Vista x64 (vm) and it works.

Yes your are right, creating a color quantization needs a deep knowledge in this area, what a pain... :oops:

Br,

UEZ

Edited by UEZ

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

Geez, I may be expecting too much, but I don't understand that what I consider an elementary operation should require deep and cutting-edge knowledge of that many Windows graphics primitives mixing DC, DDB, DIB, and much more. I'm not complaining, just perplex.

Windows implements mostly stuff to display graphical user interfaces, gdi+ extends it a bit, but I feel anything not directly related to displaying images is lacking. To create images with a specific format, I prefer FreeImage which implements a large variety of conversion functions for free :oops: Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

  • 2 years later...

Hello

I know the topic has a little more than two years, but some things are valid for long!



@UEZ
To get the same effect from the palette of 256 colors using AutoIt, I think it's very complicated, at least for me, so thats why i did the code in C++ for this my topic and here is the snippet responsible for obtaining an image in 8bit-256 colors and not only in grayscale mode:
if (iColor) { // 256 colors
                // Windows reserves first color for white,
                pbmi->bmiColors[0].rgbRed = 255;
                pbmi->bmiColors[0].rgbGreen = 255;
                pbmi->bmiColors[0].rgbBlue = 255;
                // and last color as black!
                pbmi->bmiColors[255].rgbRed = 0;
                pbmi->bmiColors[255].rgbGreen = 0;
                pbmi->bmiColors[255].rgbBlue = 0;

                i = 20; // first 20 and last 20 are reserved
                for (red = 0; red <= 255; red+= 51) {// the six values of red
                    for (green = 0; green <= 255; green += 51) {
                        for (blue = 0; blue <= 255; blue+= 51) {
                            pbmi->bmiColors[i].rgbRed = red;
                            pbmi->bmiColors[i].rgbGreen = green;
                            pbmi->bmiColors[i].rgbBlue = blue;
                            pbmi->bmiColors[i].rgbReserved = 0;
                            ++i;
                        }
                    }
                }

Anyone who can translate the snippet above to AutoIt, let us know!

Until this not happens, I made a small change to your code for 8-bit with 256 colors, see:

;coded by eukalyptus
#include <ScreenCapture.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>


$filename = @ScriptDir & "Test.png"
$bits = 8 ;1, 4, 8 only possible

$hHBitmap = _ScreenCapture_Capture("", 0, 0, 300, 300)
$hHBitmap2 = _Convert($hHBitmap, $bits)

$hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap2)

_ScreenCapture_SaveImage($filename, $hHBitmap2)

_WinAPI_DeleteObject($hHBitmap)
_WinAPI_DeleteObject($hHBitmap2)

ShellExecute($filename)

Exit

Func _Convert($hHBitmap, $iBPP) ;function by eukalyptus

    Local $tBitmap = DllStructCreate("long bmType; long bmWidth; long bmHeight; long bmWidthBytes; ushort bmPlanes; ushort bmBitsPixel; ptr bmBits;")
    DllCall('gdi32.dll', 'int', 'GetObject', 'int', $hHBitmap, 'int', DllStructGetSize($tBitmap), 'ptr', DllStructGetPtr($tBitmap))
    Local $iWidth = DllStructGetData($tBitmap, "bmWidth")
    Local $iHeight = DllStructGetData($tBitmap, "bmHeight")

    Switch $iBPP
        Case 1, 4, 8

        Case Else
            Return SetError(1, 1, False)
    EndSwitch


    Local $tBITMAPINFO = DllStructCreate("dword Size; long Width; long Height; word Planes; word BitCount; dword Compression; dword SizeImage; long XPelsPerMeter; long YPelsPerMeter; dword ClrUsed; dword ClrImportant; dword RGBQuad[256];")
    DllStructSetData($tBITMAPINFO, 'Size', 40)
    DllStructSetData($tBITMAPINFO, 'Width', $iWidth)
    DllStructSetData($tBITMAPINFO, 'Height', -$iHeight)
    DllStructSetData($tBITMAPINFO, 'Planes', 1)
    DllStructSetData($tBITMAPINFO, 'BitCount', $iBPP)

    Local $iColorCnt = BitShift(1, -$iBPP)

    DllStructSetData($tBITMAPINFO, 'ClrUsed', $iColorCnt)
    DllStructSetData($tBITMAPINFO, 'ClrImportant', $iColorCnt)

    Switch $iBPP
        Case 1
            DllStructSetData($tBITMAPINFO, 'RGBQuad', BitOR(BitShift(0xFF, -16), BitShift(0xFF, -8), 0xFF), 2)

        Case 4
            Local $aCol[16] = [8, 24, 38, 56, 72, 88, 104, 120, 136, 152, 168, 184, 210, 216, 232, 248]
            For $i = 0 To 15
                DllStructSetData($tBITMAPINFO, 'RGBQuad', BitOR(BitShift($aCol[$i], -16), BitShift($aCol[$i], -8), $aCol[$i]), $i + 1)
            Next

        Case 8
            ; Windows reserves first color for white,
            DllStructSetData($tBITMAPINFO, 'RGBQuad', 255, 1)
            ; and last color as black!
            DllStructSetData($tBITMAPINFO, 'RGBQuad', 0, 255)

            Local $iColor = 10

            For $i = 20 To $iColorCnt - 22 ;first 20 and last 20 are reserved!
                DllStructSetData($tBITMAPINFO, 'RGBQuad', BitOR(BitShift($i, -16), BitShift($i, -8), $i*$iColor), $i + 1)
            Next

    EndSwitch

    Local $hDCD = _WinAPI_CreateCompatibleDC(0)
    Local $hDCS = _WinAPI_CreateCompatibleDC($hDCD)
    Local $aRet = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBITMAPINFO), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'dword', 0)
    Local $hHBmp = $aRet[0]
    Local $hOrigD = _WinAPI_SelectObject($hDCD, $hHBmp)
    Local $hOrigS = _WinAPI_SelectObject($hDCS, $hHBitmap)

    _WinAPI_BitBlt($hDCD, 0, 0, $iWidth, $iHeight, $hDCS, 0, 0, $SRCCOPY)

    _WinAPI_SelectObject($hDCD, $hOrigD)
    _WinAPI_SelectObject($hDCS, $hOrigS)
    _WinAPI_DeleteDC($hDCD)
    _WinAPI_DeleteDC($hDCS)

    Return $hHBmp
EndFunc   ;==>_Convert

Change the value of $iColor for other shades

JS

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

This seems to be more realistic (image look):

Case 8
            ; Windows reserves first color for white,
            $tBITMAPINFO.RGBQuad((0)) = 0xFFFFFF
            ; and last color as black!
            $tBITMAPINFO.RGBQuad((0xFF)) = 0x000000

            Local $iColor = 20, $iRed, $iGreen, $iBlue
            For $iRed = 0 To 255 Step 51
                For $iGreen = 0 To 255 Step 51
                    For $iBlue = 0 To 255 Step 51
                        $tBITMAPINFO.RGBQuad(($iColor)) = BitShift($iRed, -16) + BitShift($iGreen, -8) + $iBlue
                        $iColor += 1
                    Next
                Next
            Next

Br,

UEZ

Edited by UEZ

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

@UEZ

Well done!

Here to 4bits-16 colors:

Case 4
            Local $aCol[16] = [8, 24, 38, 56, 72, 88, 104, 120, 136, 152, 168, 184, 210, 216, 232, 248]

            Local $iColor = 12

            For $i = 0 To 15
                DllStructSetData($tBITMAPINFO, 'RGBQuad', BitOR(BitShift($aCol[$i], -16), BitShift($aCol[$i], -8), $aCol[$i]*$iColor), $i + 1)
            Next

If you have a better idea...

JS

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

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