flet Posted August 8, 2011 Posted August 8, 2011 (edited) I have found two functions in different topics on this forum for converting an image to a 2d-array and for 2d-array back to an image again. However, when I convert the image stored in a 2d-array back to the real image, the colors have changed. I have been playing with: $aArray[$i][$j] = Hex(DllStructGetData($v_Buffer, 1), 6) and $aArray[$i][$j] = Hex(DllStructGetData($v_Buffer, 1), 8)(see code below), but to no avail. Is there someone who can help me (or explain to me where it goes wrong)? Is it because in the 1st function vBuffer works with dword and in the second with byte? expandcollapse popup#include <GDIPlus.au3> #include <Array.au3> #include <WinAPI.au3> Opt("MustDeclareVars", 1) _GDIPlus_Startup() Dim $pixelarray Local $file_in = "image1-before.jpg" Local $file_out = "image1-after.jpg" _FileImageToArray($file_in, $pixelarray) ; do some pixelpower stuff here... ;_ArrayDisplay($pixelarray) _FileArrayToImage($file_out, $pixelarray) _GDIPlus_Shutdown() ; code by Malkey: thanks man! Func _FileImageToArray($filename, ByRef $aArray) Local $Reslt, $stride, $format, $Scan0, $iW, $iH, $hImage Local $v_Buffer, $width, $height Local $i, $j $hImage = _GDIPlus_ImageLoadFromFile($filename) $iW = _GDIPlus_ImageGetWidth($hImage) $iH = _GDIPlus_ImageGetHeight($hImage) $Reslt = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32ARGB) ;Get the returned values of _GDIPlus_BitmapLockBits () $width = DllStructGetData($Reslt, "width") $height = DllStructGetData($Reslt, "height") $stride = DllStructGetData($Reslt, "stride") $format = DllStructGetData($Reslt, "format") $Scan0 = DllStructGetData($Reslt, "Scan0") Dim $aArray[$width][$height] For $i = 0 To $iW - 1 For $j = 0 To $iH - 1 $v_Buffer = DllStructCreate("dword", $Scan0 + ($j * $stride) + ($i * 4)) $aArray[$i][$j] = Hex(DllStructGetData($v_Buffer, 1), 8) Next Next _GDIPlus_BitmapUnlockBits($hImage, $Reslt) _GDIPlus_ImageDispose($hImage) Return EndFunc ;==>_FileImageToArray ; code by Malkey: thanks again ;) Func _FileArrayToImage($filename, $aArray) Local $iW = UBound($aArray, 1), $iH = UBound($aArray, 2), $sResult = "" Local $hBMP, $hImage1, $Reslt, $width, $height, $stride, $format, $Scan0 Local $sResult, $v_BufferA Local $i, $j $hBMP = _WinAPI_CreateBitmap($iW, $iH, 1, 32) $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) $Reslt = _GDIPlus_BitmapLockBits($hImage1, 0, 0, $iW, $iH, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) ;Get the returned values of _GDIPlus_BitmapLockBits () $width = DllStructGetData($Reslt, "width") $height = DllStructGetData($Reslt, "height") $stride = DllStructGetData($Reslt, "stride") $format = DllStructGetData($Reslt, "format") $Scan0 = DllStructGetData($Reslt, "Scan0") $v_BufferA = DllStructCreate("byte[" & $height * $width * 4 & "]", $Scan0) ;$AllPixels = DllStructGetData($v_BufferA, 1) For $j = 0 To $height - 1 For $i = 0 To $width - 1 $sResult &= Hex($aArray[$i][$j], 8) Next Next DllStructSetData($v_BufferA, 1, "0x" & StringStripWS($sResult, 8)) _GDIPlus_BitmapUnlockBits($hImage1, $Reslt) _GDIPlus_ImageSaveToFile($hImage1, $filename) _GDIPlus_ImageDispose($hImage1) _WinAPI_DeleteObject($hBMP) Return EndFunc ;==>_FileArrayToImage EDIT: Solved Edited August 10, 2011 by flet
Malkey Posted August 8, 2011 Posted August 8, 2011 In the _FileArrayToImage() function, change $sResult &= Hex($aArray[$i][$j], 8) to $sResult &= StringRegExpReplace($aArray[$i][$j],"(..)(..)(..)(..)","\4\3\2\1") The data format of the pixels in the array is "0xAARRGGBB" [From Hex(DllStructGetData($v_Buffer, 1), 8) ]. Then the raw data format of the pixels for the file needs to be "0xBBGGRRAA".
UEZ Posted August 8, 2011 Posted August 8, 2011 Here the mod. version: expandcollapse popup#include <GDIPlus.au3> #include <Array.au3> #include <WinAPI.au3> Opt("MustDeclareVars", 1) _GDIPlus_Startup() Dim $pixelarray Local $file_in = "test_.jpg" Local $file_out = "test_2.jpg" _FileImageToArray($file_in, $pixelarray) ;~ _ArrayDisplay($pixelarray) ; do some pixelpower stuff here... ;~ _ArrayDisplay($pixelarray) _FileArrayToImage($file_out, $pixelarray) _GDIPlus_Shutdown() ShellExecute($file_out) ; code by Malkey: thanks man! Func _FileImageToArray($filename, ByRef $aArray) Local $Reslt, $stride, $format, $Scan0, $iW, $iH, $hImage Local $v_Buffer, $width, $height Local $i, $j $hImage = _GDIPlus_ImageLoadFromFile($filename) $iW = _GDIPlus_ImageGetWidth($hImage) $iH = _GDIPlus_ImageGetHeight($hImage) $Reslt = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32ARGB) ;Get the returned values of _GDIPlus_BitmapLockBits () $width = DllStructGetData($Reslt, "width") $height = DllStructGetData($Reslt, "height") $stride = DllStructGetData($Reslt, "stride") $format = DllStructGetData($Reslt, "format") $Scan0 = DllStructGetData($Reslt, "Scan0") Dim $aArray[$width][$height] For $i = 0 To $iW - 1 For $j = 0 To $iH - 1 $v_Buffer = DllStructCreate("dword", $Scan0 + ($j * $stride) + ($i * 4)) $aArray[$i][$j] = Hex(DllStructGetData($v_Buffer, 1)) Next Next _GDIPlus_BitmapUnlockBits($hImage, $Reslt) _GDIPlus_ImageDispose($hImage) Return EndFunc ;==>_FileImageToArray ; code by Malkey: thanks again ;) Func _FileArrayToImage($filename, $aArray) Local $iW = UBound($aArray, 1), $iH = UBound($aArray, 2), $sResult = "" Local $hBMP, $hImage1, $Reslt, $width, $height, $stride, $format, $Scan0 Local $sResult, $v_BufferA Local $i, $j $hBMP = _WinAPI_CreateBitmap($iW, $iH, 1, 32) $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) $Reslt = _GDIPlus_BitmapLockBits($hImage1, 0, 0, $iW, $iH, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) ;Get the returned values of _GDIPlus_BitmapLockBits () $width = DllStructGetData($Reslt, "width") $height = DllStructGetData($Reslt, "height") $stride = DllStructGetData($Reslt, "stride") $format = DllStructGetData($Reslt, "format") $Scan0 = DllStructGetData($Reslt, "Scan0") $v_BufferA = DllStructCreate("byte[" & $height * $width * 4 & "]", $Scan0) ;$AllPixels = DllStructGetData($v_BufferA, 1) For $j = 0 To $height - 1 For $i = 0 To $width - 1 $sResult &= Swap($aArray[$i][$j]) Next Next DllStructSetData($v_BufferA, 1, Binary("0x" & $sResult)) _GDIPlus_BitmapUnlockBits($hImage1, $Reslt) _GDIPlus_ImageSaveToFile($hImage1, $filename) _GDIPlus_ImageDispose($hImage1) _WinAPI_DeleteObject($hBMP) Return EndFunc ;==>_FileArrayToImage Func Swap($hs) Local $a = StringMid($hs, 1, 2) Local $r = StringMid($hs, 3, 2) Local $g = StringMid($hs, 5, 2) Local $b = StringMid($hs, 7, 2) Return $b & $g & $r & $a EndFunc The Swap function can be done faster... 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
Malkey Posted August 9, 2011 Posted August 9, 2011 To avoid having to convert the pixel format when writing from the array to the image, this example uses the DllStructSetData() function. expandcollapse popup#include <GDIPlus.au3> #include <Array.au3> #include <WinAPI.au3> Opt("MustDeclareVars", 1) _GDIPlus_Startup() Dim $pixelarray Local $file_in = "Bckgrnd.jpg" ; "image1-before.jpg" ; Local $file_out = "image1-after.jpg" _FileImageToArray($file_in, $pixelarray) ; do some pixelpower stuff here... ;_ArrayDisplay($pixelarray) _FileArrayToImage($file_out, $pixelarray) _GDIPlus_Shutdown() ; code by Malkey: thanks man! Func _FileImageToArray($filename, ByRef $aArray) Local $Reslt, $stride, $format, $Scan0, $iW, $iH, $hImage Local $v_Buffer, $width, $height Local $i, $j $hImage = _GDIPlus_ImageLoadFromFile($filename) $iW = _GDIPlus_ImageGetWidth($hImage) $iH = _GDIPlus_ImageGetHeight($hImage) $Reslt = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32ARGB) ;Get the returned values of _GDIPlus_BitmapLockBits () $width = DllStructGetData($Reslt, "width") $height = DllStructGetData($Reslt, "height") $stride = DllStructGetData($Reslt, "stride") $format = DllStructGetData($Reslt, "format") $Scan0 = DllStructGetData($Reslt, "Scan0") Dim $aArray[$width][$height] For $i = 0 To $iW - 1 For $j = 0 To $iH - 1 $v_Buffer = DllStructCreate("dword", $Scan0 + ($j * $stride) + ($i * 4)) $aArray[$i][$j] = Hex(DllStructGetData($v_Buffer, 1), 8) Next Next _GDIPlus_BitmapUnlockBits($hImage, $Reslt) _GDIPlus_ImageDispose($hImage) Return EndFunc ;==>_FileImageToArray ; code by Malkey: thanks again ;) Func _FileArrayToImage($filename, $aArray) Local $iW = UBound($aArray, 1), $iH = UBound($aArray, 2), $sResult = "" Local $hBMP, $hImage1, $Reslt, $width, $height, $stride, $format, $Scan0 Local $sResult, $v_BufferA Local $i, $j $hBMP = _WinAPI_CreateBitmap($iW, $iH, 1, 32) $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) $Reslt = _GDIPlus_BitmapLockBits($hImage1, 0, 0, $iW, $iH, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) ;Get the returned values of _GDIPlus_BitmapLockBits () $width = DllStructGetData($Reslt, "width") $height = DllStructGetData($Reslt, "height") $stride = DllStructGetData($Reslt, "stride") $format = DllStructGetData($Reslt, "format") $Scan0 = DllStructGetData($Reslt, "Scan0") $v_BufferA = DllStructCreate("DWORD[" & $height * $width & "]", $Scan0) For $j = 0 To $height - 1 For $i = 0 To $width - 1 DllStructSetData($v_BufferA, 1, Execute("0x" & $aArray[$i][$j]), ($j * $width) + $i + 1) ; "+1" - base 1. Next Next _GDIPlus_BitmapUnlockBits($hImage1, $Reslt) _GDIPlus_ImageSaveToFile($hImage1, $filename) _GDIPlus_ImageDispose($hImage1) _WinAPI_DeleteObject($hBMP) Return EndFunc ;==>_FileArrayToImage
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now