GodlessSinner Posted September 9, 2010 Share Posted September 9, 2010 (edited) expandcollapse popup#Include <GDIPlus.au3> #include <ScreenCapture.au3> _GDIPlus_Startup() _ScreenCapture_SetJPGQuality(20) _ScreenCapture_Capture("test.jpg",0,0,100,100) $hImage1 = _GDIPlus_ImageLoadFromFile("test.jpg") ;$hImage1 = _GDIPlus_BitmapCreateFromHBITMAP(_ScreenCapture_Capture("",0,0,100,100)) $hImage2 = _GDIPlus_ImageGreyscale($hImage1) _GDIPlus_ImageSaveToFile($hImage2, "test_grey.jpg") _GDIPlus_ImageDispose($hImage1) _GDIPlus_ImageDispose($hImage2) _GDIPlus_ShutDown() Exit ;; _GDIPlus_ImageGreyscale() ;; Creates a greyscale copy of Image object and returns its handle. To destroy it, use _GDIPlus_ImageDispose() or _GDIPlus_BitmapDispose() Func _GDIPlus_ImageGreyscale(Const ByRef $hImage) Local $tColorMatrix, $x, $hImgAttrib, $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage), $hGraphics, $hGraphics2, $hBitmap ;;create color matrix data $tColorMatrix = DllStructCreate("float[5];float[5];float[5];float[5];float[5]") ;greyscale values: $x = DllStructSetData($tColorMatrix, 1, 0.3, 1) * DllStructSetData($tColorMatrix, 1, 0.3, 2) * DllStructSetData($tColorMatrix, 1, 0.3, 3) * _ DllStructSetData($tColorMatrix, 2, 0.59, 1) * DllStructSetData($tColorMatrix, 2, 0.59, 2) * DllStructSetData($tColorMatrix, 2, 0.59, 3) * _ DllStructSetData($tColorMatrix, 3, 0.11, 1) * DllStructSetData($tColorMatrix, 3, 0.11, 2) * DllStructSetData($tColorMatrix, 3, 0.11, 3) * _ DllStructSetData($tColorMatrix, 4, 1.0, 4) * _ DllStructSetData($tColorMatrix, 5, 1.0, 5) ;;create an image attributes object and update its color matrix $hImgAttrib = _GDIPlus_ImageAttributesCreate() _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, 1, DllStructGetPtr($tColorMatrix)) ;;copy image $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage) $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) $hGraphics2 = _GDIPlus_ImageGetGraphicsContext($hBitmap) ;;draw original into copy with attributes _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics2, $hImage, 0, 0, $iW, $iH, 0, 0, $iW, $iH, 2, $hImgAttrib) ;;clean up _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_GraphicsDispose($hGraphics2) _GDIPlus_ImageAttributesDispose($hImgAttrib) Return $hBitmap EndFunc Func _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, $iColorAdjustType, $pColorMatrix = 0, $pGrayMatrix = 0, $iColorMatrixFlags = 0) Local $fEnable = 1, $aResult = DllCall($ghGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr",$hImgAttrib, "int",$iColorAdjustType, _ "int",$fEnable, "ptr",$pColorMatrix, "ptr",$pGrayMatrix, "int",$iColorMatrixFlags) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;;Creates ImageAttributes object Func _GDIPlus_ImageAttributesCreate() Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateImageAttributes", "ptr*", 0) Return SetError($aResult[0], 0, $aResult[1]) EndFunc ;;Deletes ImageAttributes object Func _GDIPlus_ImageAttributesDispose($hImgAttrib) Local $aResult = DllCall($ghGDIPDll, "int", "GdipDisposeImageAttributes", "ptr", $hImgAttrib) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;; _GDIPlus_GraphicsDrawImageRectRectEx() ;; Same as _GDIPlus_GraphicsDrawImageRectRect(), but adds 1 optional parameter - $hImgAttrib (handle to ImageAttributes object) Func _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics, $hImage, $iSrcX, $iSrcY, $iSrcWidth, $iSrcHeight, $iDstX, $iDstY, $iDstWidth, $iDstHeight, $iUnit = 2, $hImgAttrib = 0) Local $aResult = DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", $hGraphics, "hwnd", $hImage, "int", $iDstX, "int", _ $iDstY, "int", $iDstWidth, "int", $iDstHeight, "int", $iSrcX, "int", $iSrcY, "int", $iSrcWidth, "int", _ $iSrcHeight, "int", $iUnit, "ptr", $hImgAttrib, "int", 0, "int", 0) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;;============================= EDIT: Saying "image size", i mean file size. Edited September 9, 2010 by GodlessSinner _____________________________________________________________________________ Link to comment Share on other sites More sharing options...
Tvern Posted September 9, 2010 Share Posted September 9, 2010 For me the greyscale image is slightly smaller than the color image. 2.63 vs 2.87 kB. This is how I think it works, but it's by no means backed up by any knowledge about the subject. It just seems to make sense. The reason the grayscale image file isn't much smaller is because both images use 24bit depth and compression quality 20. In short they can both hold about 16m different color variations (2^24), but for the greyscale image they are all shades of grey. Link to comment Share on other sites More sharing options...
UEZ Posted September 10, 2010 Share Posted September 10, 2010 (edited) expandcollapse popup#Include <GDIPlus.au3> #include <ScreenCapture.au3> _GDIPlus_Startup() _ScreenCapture_SetJPGQuality(20) _ScreenCapture_Capture("test.jpg",0,0,100,100) $hImage1 = _GDIPlus_ImageLoadFromFile("test.jpg") ;$hImage1 = _GDIPlus_BitmapCreateFromHBITMAP(_ScreenCapture_Capture("",0,0,100,100)) $hImage2 = _GDIPlus_ImageGreyscale($hImage1) _GDIPlus_ImageSaveToFile($hImage2, "test_grey.jpg") _GDIPlus_ImageDispose($hImage1) _GDIPlus_ImageDispose($hImage2) _GDIPlus_ShutDown() Exit ;; _GDIPlus_ImageGreyscale() ;; Creates a greyscale copy of Image object and returns its handle. To destroy it, use _GDIPlus_ImageDispose() or _GDIPlus_BitmapDispose() Func _GDIPlus_ImageGreyscale(Const ByRef $hImage) Local $tColorMatrix, $x, $hImgAttrib, $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage), $hGraphics, $hGraphics2, $hBitmap ;;create color matrix data $tColorMatrix = DllStructCreate("float[5];float[5];float[5];float[5];float[5]") ;greyscale values: $x = DllStructSetData($tColorMatrix, 1, 0.3, 1) * DllStructSetData($tColorMatrix, 1, 0.3, 2) * DllStructSetData($tColorMatrix, 1, 0.3, 3) * _ DllStructSetData($tColorMatrix, 2, 0.59, 1) * DllStructSetData($tColorMatrix, 2, 0.59, 2) * DllStructSetData($tColorMatrix, 2, 0.59, 3) * _ DllStructSetData($tColorMatrix, 3, 0.11, 1) * DllStructSetData($tColorMatrix, 3, 0.11, 2) * DllStructSetData($tColorMatrix, 3, 0.11, 3) * _ DllStructSetData($tColorMatrix, 4, 1.0, 4) * _ DllStructSetData($tColorMatrix, 5, 1.0, 5) ;;create an image attributes object and update its color matrix $hImgAttrib = _GDIPlus_ImageAttributesCreate() _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, 1, DllStructGetPtr($tColorMatrix)) ;;copy image $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage) $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) $hGraphics2 = _GDIPlus_ImageGetGraphicsContext($hBitmap) ;;draw original into copy with attributes _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics2, $hImage, 0, 0, $iW, $iH, 0, 0, $iW, $iH, 2, $hImgAttrib) ;;clean up _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_GraphicsDispose($hGraphics2) _GDIPlus_ImageAttributesDispose($hImgAttrib) Return $hBitmap EndFunc Func _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, $iColorAdjustType, $pColorMatrix = 0, $pGrayMatrix = 0, $iColorMatrixFlags = 0) Local $fEnable = 1, $aResult = DllCall($ghGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr",$hImgAttrib, "int",$iColorAdjustType, _ "int",$fEnable, "ptr",$pColorMatrix, "ptr",$pGrayMatrix, "int",$iColorMatrixFlags) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;;Creates ImageAttributes object Func _GDIPlus_ImageAttributesCreate() Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateImageAttributes", "ptr*", 0) Return SetError($aResult[0], 0, $aResult[1]) EndFunc ;;Deletes ImageAttributes object Func _GDIPlus_ImageAttributesDispose($hImgAttrib) Local $aResult = DllCall($ghGDIPDll, "int", "GdipDisposeImageAttributes", "ptr", $hImgAttrib) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;; _GDIPlus_GraphicsDrawImageRectRectEx() ;; Same as _GDIPlus_GraphicsDrawImageRectRect(), but adds 1 optional parameter - $hImgAttrib (handle to ImageAttributes object) Func _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics, $hImage, $iSrcX, $iSrcY, $iSrcWidth, $iSrcHeight, $iDstX, $iDstY, $iDstWidth, $iDstHeight, $iUnit = 2, $hImgAttrib = 0) Local $aResult = DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", $hGraphics, "hwnd", $hImage, "int", $iDstX, "int", _ $iDstY, "int", $iDstWidth, "int", $iDstHeight, "int", $iSrcX, "int", $iSrcY, "int", $iSrcWidth, "int", _ $iSrcHeight, "int", $iUnit, "ptr", $hImgAttrib, "int", 0, "int", 0) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;;============================= EDIT: Saying "image size", i mean file size. You are making a screenshot and saving it with quality 20, afterwards you are loading the saved image and converting it to greyscale and finally you save the greyscaled image! First: you are loading the compressed image with more artefacts as the orginal image which means a higher file size when saving it back. Second: saving the second image back is with standard quality settings only which means automatically a higher file size than the 1st image with quality 20! Third: after converting the image to greyscale it has still 24bpp and not 8bpp which has also an impact to the file size! Currently I didn't investigate how to convert a 32/24bpp to 8bpp but here the code that saves the 2nd image also with quality 20. expandcollapse popup#Include <GDIPlus.au3> #include <ScreenCapture.au3> _GDIPlus_Startup() _ScreenCapture_SetJPGQuality(20) _ScreenCapture_Capture("test.jpg",0,0,100,100) $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP(_ScreenCapture_Capture("",0,0,100,100)) ;$hImage1 = _GDIPlus_BitmapCreateFromHBITMAP(_ScreenCapture_Capture("",0,0,100,100)) $hImage2 = _GDIPlus_ImageGreyscale($hImage1) $sCLSID = _GDIPlus_EncodersGetCLSID ("JPG") $tParams = _GDIPlus_ParamInit (1) $tData = DllStructCreate("int Quality") DllStructSetData($tData, "Quality", 20) ;quality 0-100 $pData = DllStructGetPtr($tData) _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData) $pParams = DllStructGetPtr($tParams) _GDIPlus_ImageSaveToFileEx($hImage2, "test_grey.jpg", $sCLSID, $pParams) $tData = 0 _GDIPlus_ImageDispose($hImage1) _GDIPlus_ImageDispose($hImage2) _GDIPlus_ShutDown() Exit ;; _GDIPlus_ImageGreyscale() ;; Creates a greyscale copy of Image object and returns its handle. To destroy it, use _GDIPlus_ImageDispose() or _GDIPlus_BitmapDispose() Func _GDIPlus_ImageGreyscale(Const ByRef $hImage) Local $tColorMatrix, $x, $hImgAttrib, $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage), $hGraphics, $hGraphics2, $hBitmap ;;create color matrix data $tColorMatrix = DllStructCreate("float[5];float[5];float[5];float[5];float[5]") ;greyscale values: $x = DllStructSetData($tColorMatrix, 1, 0.3, 1) * DllStructSetData($tColorMatrix, 1, 0.3, 2) * DllStructSetData($tColorMatrix, 1, 0.3, 3) * _ DllStructSetData($tColorMatrix, 2, 0.59, 1) * DllStructSetData($tColorMatrix, 2, 0.59, 2) * DllStructSetData($tColorMatrix, 2, 0.59, 3) * _ DllStructSetData($tColorMatrix, 3, 0.11, 1) * DllStructSetData($tColorMatrix, 3, 0.11, 2) * DllStructSetData($tColorMatrix, 3, 0.11, 3) * _ DllStructSetData($tColorMatrix, 4, 1.0, 4) * _ DllStructSetData($tColorMatrix, 5, 1.0, 5) ;;create an image attributes object and update its color matrix $hImgAttrib = _GDIPlus_ImageAttributesCreate() _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, 1, DllStructGetPtr($tColorMatrix)) ;;copy image $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage) $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) $hGraphics2 = _GDIPlus_ImageGetGraphicsContext($hBitmap) ;;draw original into copy with attributes _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics2, $hImage, 0, 0, $iW, $iH, 0, 0, $iW, $iH, 2, $hImgAttrib) ;;clean up _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_GraphicsDispose($hGraphics2) _GDIPlus_ImageAttributesDispose($hImgAttrib) Return $hBitmap EndFunc Func _GDIPlus_ImageAttributesSetColorMatrix($hImgAttrib, $iColorAdjustType, $pColorMatrix = 0, $pGrayMatrix = 0, $iColorMatrixFlags = 0) Local $fEnable = 1, $aResult = DllCall($ghGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr",$hImgAttrib, "int",$iColorAdjustType, _ "int",$fEnable, "ptr",$pColorMatrix, "ptr",$pGrayMatrix, "int",$iColorMatrixFlags) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;;Creates ImageAttributes object Func _GDIPlus_ImageAttributesCreate() Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateImageAttributes", "ptr*", 0) Return SetError($aResult[0], 0, $aResult[1]) EndFunc ;;Deletes ImageAttributes object Func _GDIPlus_ImageAttributesDispose($hImgAttrib) Local $aResult = DllCall($ghGDIPDll, "int", "GdipDisposeImageAttributes", "ptr", $hImgAttrib) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;; _GDIPlus_GraphicsDrawImageRectRectEx() ;; Same as _GDIPlus_GraphicsDrawImageRectRect(), but adds 1 optional parameter - $hImgAttrib (handle to ImageAttributes object) Func _GDIPlus_GraphicsDrawImageRectRectEx($hGraphics, $hImage, $iSrcX, $iSrcY, $iSrcWidth, $iSrcHeight, $iDstX, $iDstY, $iDstWidth, $iDstHeight, $iUnit = 2, $hImgAttrib = 0) Local $aResult = DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", $hGraphics, "hwnd", $hImage, "int", $iDstX, "int", _ $iDstY, "int", $iDstWidth, "int", $iDstHeight, "int", $iSrcX, "int", $iSrcY, "int", $iSrcWidth, "int", _ $iSrcHeight, "int", $iUnit, "ptr", $hImgAttrib, "int", 0, "int", 0) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;;============================= I assume that the file size of both image should be nearly the same. Br, UEZ Edited September 10, 2010 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 More sharing options...
Tvern Posted September 10, 2010 Share Posted September 10, 2010 (edited) Looking at the screencapture function, it should be possible to take the return value from that function and then save it as a jpg with the desired properties. That would eliminate quality loss by using a the compressed in-between image and should allow for a smaller filesize. Going to have a shot at it. Edit: Just noticed the line that was commented out in UEZ' script doing just what I had in mind, except for reducing the bpp. I can't seem to get the settings for lowering the bpp right though. Edited September 10, 2010 by Tvern Link to comment Share on other sites More sharing options...
GodlessSinner Posted September 10, 2010 Author Share Posted September 10, 2010 UEZ, big thanks! Would be perfect to convert to 8bpp, just I need to decrease quality so much, as possible, and keeping text's readability. _____________________________________________________________________________ Link to comment Share on other sites More sharing options...
MvGulik Posted September 10, 2010 Share Posted September 10, 2010 (edited) ... keeping text's readability ... 4bpp(16gray), 1bpp(B/W, fax) Erm. JPG supporting those? (think not.) Edited September 10, 2010 by MvGulik "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... Link to comment Share on other sites More sharing options...
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