Sign in to follow this  
Followers 0
qwert

Need advice on simplest image conversion of all

7 posts in this topic

I'm back researching a problem that I tried and failed to solve with AutoIt nearly 10 years ago:  Pure black and white

I have images that are essentially black and white ... not grayscale ... in JPG files.  As the histogram example below shows, the individual picture elements are clearly either above 128, or below.

Off and on, I've tried a dozen variations of conversions, but I've never been able to get the kind of "reduction" I'm looking for.  I would expect the 15Mb file in this example to reduce to far less than one Mb. Ideally, the 24bit parameter would become a single bit per pixel. But no format seems to support that level of reduction.

At this point, I'm back looking for a viable direction to take.  Can someone suggest image functions that I should be considering?

Thanks in advance for any help.

 

Simple situation.png

Share this post


Link to post
Share on other sites



Can you attach a sample file?

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Here's a "small" example ... a single page.  Originally, it was 1.7Mb, but I reduced it to fit the forum limits.

Spoiler

reduced from 1+Mb.jpg

 

Edited by qwert

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Try something like this here:

 

#include <GDIPlus.au3>

_GDIPlus_Startup()

Global Const $hImage = _GDIPlus_ImageLoadFromFile("Example_1200w.jpg") ;your image file
Global $aDim = _GDIPlus_ImageGetDimension($hImage)

#Region methode 1
Global $hImage_BW = _GDIPlus_BitmapCreateFromScan0($aDim[0], $aDim[1], $GDIP_PXF01INDEXED), $hGfx = _GDIPlus_ImageGetGraphicsContext($hImage_BW)
_GDIPlus_GraphicsDrawImageRect($hGfx, $hImage, 0, 0, $aDim[0], $aDim[1])
_GDIPlus_ImageSaveToFile($hImage_BW, "Example_1200w_bw1.png") 
_GDIPlus_GraphicsDispose($hGfx)
_GDIPlus_ImageDispose($hImage_BW)
#EndRegion

#Region methode 2
$hImage_BW = _GDIPlus_BitmapCreateFromScan0($aDim[0], $aDim[1], $GDIP_PXF01INDEXED)
$hGfx = _GDIPlus_ImageGetGraphicsContext($hImage_BW)
Global $iThreshold = 64 ;A value between 0 and 255. The lower the value the darker the result
Global Const $hIA = _GDIPlus_ImageAttributesCreate()
Global Const $tColorMatrix = _GDIPlus_ColorMatrixCreateGrayScale()
_GDIPlus_ImageAttributesSetThreshold($hIA, 0, True, $iThreshold)
_GDIPlus_ImageAttributesSetColorMatrix($hIA, 0, True, DllStructGetPtr($tColorMatrix))
_GDIPlus_GraphicsDrawImageRectRect($hGfx, $hImage, 0, 0, $aDim[0], $aDim[1], 0, 0, $aDim[0], $aDim[1], $hIA)
_GDIPlus_ImageAttributesDispose($hIA)
_GDIPlus_ImageSaveToFile($hImage_BW, "Example_1200w_bw2.png")
_GDIPlus_GraphicsDispose($hGfx)
_GDIPlus_ImageDispose($hImage_BW)
#EndRegion

_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()

Func _GDIPlus_ImageAttributesSetThreshold($hImageAttributes, $iColorAdjustType = 0, $fEnable = False, $nThershold = 0)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetImageAttributesThreshold", "handle", $hImageAttributes, "int", $iColorAdjustType, "int", $fEnable, "float", $nThershold)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_ImageAttributesSetThreshold

 

Btw, your image is not b/w rather greyscaled (256 colors) which is also shown in the histogram.

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!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

@UEZ: Indeed, my original is greyscale.  What I was trying to say was that, logically, there is only "content" on a white background.  I'm trying to extract the content, of course.

So far, I've gotten the best results by using your method 2, with a threshold of 55.  Yet, it's not quite up to what I would deem good.  What I'm now thinking, is that I may need to tune the page's contrast and brightness PRIOR TO using method 2. Beyond that, I guess pixel-level processing might be able to look for transitions greater than, say, 30%. But I probably can't justify going to that level ... which is probably what OCR programs do.

But, regardless, you've provided a great starting point.  Thanks for that.

 

Compare.jpg

Edited by qwert

Share this post


Link to post
Share on other sites

You might combine some of the other FX:

#Region methode 2
$hImage_BW = _GDIPlus_BitmapCreateFromScan0($aDim[0], $aDim[1], $GDIP_PXF01INDEXED)
$hGfx = _GDIPlus_ImageGetGraphicsContext($hImage_BW)
Global Const $hEffect_BC = _GDIPlus_EffectCreateBrightnessContrast(-5, -40)
_GDIPlus_BitmapApplyEffect($hImage, $hEffect_BC)
Global Const $hEffect_Sharpen = _GDIPlus_EffectCreateSharpen(20, 80)
_GDIPlus_BitmapApplyEffect($hImage, $hEffect_Sharpen)
Global $iThreshold = 90 ;A value between 0 and 255. The lower the value the darker the result
Global Const $hIA = _GDIPlus_ImageAttributesCreate()
Global Const $tColorMatrix = _GDIPlus_ColorMatrixCreateGrayScale()
_GDIPlus_ImageAttributesSetThreshold($hIA, 0, True, $iThreshold)
_GDIPlus_ImageAttributesSetColorMatrix($hIA, 0, True, DllStructGetPtr($tColorMatrix))
_GDIPlus_GraphicsDrawImageRectRect($hGfx, $hImage, 0, 0, $aDim[0], $aDim[1], 0, 0, $aDim[0], $aDim[1], $hIA)
_GDIPlus_ImageAttributesDispose($hIA)
 _GDIPlus_EffectDispose($hEffect_Sharpen)
 _GDIPlus_EffectDispose($hEffect_BC)
_GDIPlus_ImageSaveToFile($hImage_BW, "Example_1200w_bw2.png")
_GDIPlus_GraphicsDispose($hGfx)
_GDIPlus_ImageDispose($hImage_BW)
#EndRegion

 


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!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

Unfortunately that is a pretty rough source for compression to black and white, you have a very large change in the contrast and black levels, even OCR would have to first see the letters before it extracts them.

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