Jump to content

Simple dither tool (freeImage frontend)


Recommended Posts

So, this is my first try posting here, and first time to use a DLL like this. Hope I do it right (admins: please correct this topic if not..)

I made this small tool to convert full-color pictures into 2bit B/W BMP (since I need this type for something work-related). The tool can convert and scale to custom size (height selected, scales proportionally). For work reasons, default settings can be integers of 300, but also user-selectable.

There are some issues, f.ex selecting a different image will not make it appear right.

So, have a go at it. If you wish to improve this, please do so and paste the result here..

Tools needed for this:

Any feedback / suggestions / comments welcomed!

My own ideas for to-do on this:

  • Overcome need to dither twice.. need to study FreeImage better.
  • Option for brightness / gamma etc (slider)
  • change preview between original and result.. or perhaps both ?
  • ability to run as command line screen (in BAT / CMD files)
just some...

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Res_Comment=This program is free of charge
#AutoIt3Wrapper_Res_Description=Dither tool for color images
#AutoIt3Wrapper_Res_Fileversion=0.4
://////=__=
://////=__=
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <resources.au3>
#include <GUIComboBox.au3>
#include <GuiConstantsEx.au3>
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
; check for DLL
#include <FreeImage.au3>
If Not FileExists(@ScriptDir & "\FreeImage.dll") Then
; Global $binDLL = __FreeImage_Inline_FreeImagedll()
; make_the_dll()
MsgBox(0, "Error", "There is no FreeImage DLL in script dir. Please correct and restart")
Exit
Else
Global $binDLL
_FreeImage_LoadDLL(@ScriptDir & "\FreeImage.dll")
_FreeImage_Initialise()
EndIf
Global $ImageHandle = -1, $i2 = -1, $WorkingFileName, $FIF, $resize = 0

Func OnAutoItExit()
If $ImageHandle <> -1 Then _FreeImage_Unload($ImageHandle)
_FreeImage_DeInitialise()
EndFunc   ;==>OnAutoItExit
; =================================================
; Define the GUI
; =================================================
#Region ### START Koda GUI section ### Form=
$Form1_1 = GUICreate("DITHER TOOL - v4", 1020, 657, -1, -1)
GUISetBkColor(0xFFFFFF)
$ShowPic = GUICtrlCreatePic("", 216, 48, 800, 600)
$Label1 = GUICtrlCreateLabel("DITHER TOOL", 8, 4, 694, 43)
GUICtrlSetFont(-1, 22, 400, 0, "Arial Unicode MS")
$Button1 = GUICtrlCreateButton("Select file here", 8, 58, 187, 81)
$ButtonDitherIt = GUICtrlCreateButton("Convert file", 8, 455, 187, 80)
$btnEXIT = GUICtrlCreateButton("EXIT", 16, 594, 113, 49)
$Resizing = GUICtrlCreateGroup("Resizing", 8, 191, 185, 121)
$R1 = GUICtrlCreateCheckbox("300 px", 16, 207, 97, 17)
$R2 = GUICtrlCreateCheckbox("600 px", 16, 223, 97, 17)
$R3 = GUICtrlCreateCheckbox("900 px", 16, 239, 97, 17)
$R4 = GUICtrlCreateCheckbox("1200 px", 16, 255, 97, 17)
$R5 = GUICtrlCreateCheckbox("Custom :", 16, 277, 73, 17)
$RCUS = GUICtrlCreateInput("200", 96, 273, 41, 21)
$Label4 = GUICtrlCreateLabel("px", 141, 276, 15, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$Infolabel4 = GUICtrlCreateLabel("READY", 736, 4, 278, 43, $SS_RIGHT)
GUICtrlSetFont(-1, 22, 400, 0, "Arial Unicode MS")
$grpFilterType = GUICtrlCreateGroup("Algorith Selection", 8, 311, 185, 121)
$cmbFilter = GUICtrlCreateCombo("Resize algorithm", 16, 398, 169, 25)
GUICtrlSetData(-1, "Box|Bicubic|Bilinear|Spline|Catmull-Rom|Lanczos3")
$Label2 = GUICtrlCreateLabel("Default: Box", 17, 380, 62, 17)
$cmbDither = GUICtrlCreateCombo("Dither Algorithm", 16, 349, 169, 25)
GUICtrlSetData(-1, "Floyd/Steinberg|Bayer2x2|Bayer8x8|Cluster6x6|Cluster8x8|Cluster16x16|Bayer16x16")
$Label3 = GUICtrlCreateLabel("Default: Floyd/Steinberg", 16, 332, 119, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$Infolabel3 = GUICtrlCreateLabel("", 8, 152, 4, 4)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
$nMsg = GUIGetMsg()
Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit
  Case $Button1
   _OpenImage()
  Case $ButtonDitherIt
   _do_magic()
  Case $btnEXIT
   If FileExists(@ScriptDir & "\FreeImage.dll") Then
    _FreeImage_DeInitialise()
    _FreeImage_UnLoadDLL() ; UNLOAD THE DLL
   EndIf
   Exit
EndSwitch
WEnd

; =================================
; FUNCTIONS
; =================================
;===============================================================================
;
; Function Name:   _do_magic
; Description:: Does the dithering of an image already loaded
; Parameter(s): none
; Requirement(s):  ImageHandle to be available as an image
; Return Value(s): none
; Author(s):       TDJ
;
;===============================================================================
;
Func _do_magic()
$newname = StringReplace($WorkingFileName, "_FI4AU3", "") ;; do not use working file name
Local $dot = StringInStr($newname, ".", 1, -1)
Local $Name = StringLeft($newname, $dot - 1)
Local $Ext = StringMid($newname, $dot)
Local $dithermethod = _GUICtrlComboBox_GetCurSel($cmbDither) - 1
If $dithermethod < 0 Then $dithermethod = 0 ; do not want zero selection...
$outname = $Name & "_DITHER" & ".bmp" ;; new name is _DITHER_something
If $i2 <> -1 Then
  _FreeImage_Unload($i2)
EndIf
If $ImageHandle <> -1 Then
  $i2 = _FreeImage_ConvertToGreyscale($ImageHandle)
  $i2 = _FreeImage_Dither($i2, $dithermethod)
  _FreeImage_SaveU($FIF_BMP, $i2, $outname)
  If GUICtrlRead($R1) = $GUI_CHECKED Then _resize_it($i2, 300, $outname)
  If GUICtrlRead($R2) = $GUI_CHECKED Then _resize_it($i2, 600, $outname)
  If GUICtrlRead($R3) = $GUI_CHECKED Then _resize_it($i2, 900, $outname)
  If GUICtrlRead($R4) = $GUI_CHECKED Then _resize_it($i2, 1200, $outname)
  If GUICtrlRead($R5) = $GUI_CHECKED Then
   ; custom resize.. need to have a number
   $cusval = Number(GUICtrlRead($RCUS))
   If IsNumber($cusval) And $cusval > 0 Then
    _resize_it($i2, GUICtrlRead($RCUS), $outname)
   Else
    #Region --- CodeWizard generated code Start ---
    ;MsgBox features: Title=Yes, Text=Yes, Buttons=OK, Icon=Warning
    MsgBox(48, "Error", "You need to have a custom numeric value larger than 0.")
    #EndRegion --- CodeWizard generated code Start ---
   EndIf
  EndIf
  FileDelete($WorkingFileName)
EndIf
GUICtrlSetData($Infolabel4, "DONE!")
Sleep(2000)
GUICtrlSetData($Infolabel4, "")
EndFunc   ;==>_do_magic
;===============================================================================
;
; Function Name:   _resize_it
; Description:: Resize an image proportionally
; Parameter(s):  $imgref : an image type _freeImage
;    $h : height desired
;    $sFile : normal name of output
; Requirement(s):  Assumed imgref is an image
; Return Value(s): none. But will save image as $sFile_$h.bmp, ex. myfile_500.bmp
; Author(s):       TDJ
;
;===============================================================================
;
Func _resize_it($imgref, $h, $sFile)
Local $filtertype
$filtertype = _GUICtrlComboBox_GetCurSel($cmbFilter) - 1
If $filtertype < 0 Then $filtertype = 0
Local $dithermethod = _GUICtrlComboBox_GetCurSel($cmbDither) - 1
If $dithermethod < 0 Then $dithermethod = 0 ; do not want zero selection...
; ratio = width/height, ex: 1000/500 = 2
; new height = 800
; width = ratio * new_height
$current_ratio = _FreeImage_GetWidth($imgref) / _FreeImage_GetHeight($imgref)
$new_width = $h * $current_ratio
$hImageResized = _FreeImage_Rescale($imgref, $new_width, $h, $filtertype)
$hImageResized = _FreeImage_Dither($hImageResized, $dithermethod) ;; otherwise we get a 256 color image.... :((
$dot = StringInStr($sFile, ".", 1, -1)
$Name = StringLeft($sFile, $dot - 1)
$Ext = StringMid($sFile, $dot)
_FreeImage_SaveU($FIF_BMP, $hImageResized, $Name & $h & ".bmp")
_FreeImage_Unload($hImageResized)
EndFunc   ;==>_resize_it

Func _OpenImage()
Local $sFile = FileOpenDialog("Choose Image", @ScriptDir, "Image Files (*.jpg;*.jpeg;*.bmp;*.gif)", 3)
If @error Then Return
If $ImageHandle <> -1 Then _FreeImage_Unload($ImageHandle)
Local $dot = StringInStr($sFile, ".", 1, -1)
Local $Name = StringLeft($sFile, $dot - 1)
Local $Ext = StringMid($sFile, $dot)
$WorkingFileName = $Name & "_FI4AU3" & $Ext
FileCopy($sFile, $WorkingFileName)
$FIF = _FreeImage_GetFileTypeU($WorkingFileName)
If $FIF = $FIF_UNKNOWN Then
  $FIF = _FreeImage_GetFIFFromFilenameU($WorkingFileName)
EndIf
$ImageHandle = _FreeImage_LoadU($FIF, $sFile)
_ShowImage()
EndFunc   ;==>_OpenImage
Func _ShowImage($myFile = "")
Local $Width, $Height
_SizeProportional($Width, $Height, 800, 600, _FreeImage_GetWidth($ImageHandle), _FreeImage_GetHeight($ImageHandle))
GUICtrlSetData($Infolabel3, _FreeImage_GetWidth($ImageHandle) & "x" & _FreeImage_GetHeight($ImageHandle))
If $myFile = "" Then
  GUICtrlSetPos($ShowPic, 216, 48, $Width, $Height)
  GUICtrlSetImage($ShowPic, $WorkingFileName)
Else
  GUICtrlSetImage($ShowPic, $myFile)
EndIf
EndFunc   ;==>_ShowImage

Func _SizeProportional(ByRef $Width, ByRef $Height, $WDesired, $HDesired, $WSrc, $HSrc)
; Prog@ndy
; thanks for your work!!!
Local $RatioDes = ($WDesired / $HDesired)
Local $CurrentRatio = ($WSrc / $HSrc)
If $CurrentRatio > $RatioDes Then ; scale height
  $Width = $WDesired
  $Height = $WDesired / $CurrentRatio
Else ; scale width
  $Width = $HDesired * $CurrentRatio
  $Height = $HDesired
EndIf
EndFunc   ;==>_SizeProportional

I am just a hobby programmer, and nothing great to publish right now.

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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...