Comic Book CBx-To-CBx Convert & Resize v1.50

DESCRIPTION

Use to convert and resize (downsample only) comic books from one format to another. It recognizes standard comic book files: .cbr (RAR), .cbz (ZIP) and .cb7 (7z) for both import and export. This should work with most of the comic books in the wild. If dealing with some other format, like PDF comic books, I recommend using ComicRack (http://comicrack.cyolito.com/) to convert first to classic .cbr, .cbz or .cb7.

2019-02-05_232428

FEATURES

  1. Dialog window for options preselection
  2. Plethora of predefined screen resolutions for:
    • Android tablets and phones
    • iPhones and iPads
    • Custom size
  3. Resize orientation modes: Auto / Force Portrait / Force Landscape
  4. Repack only option (skip resizing images)
  5. Conversion image quality can be changed
  6. Export to either home source or destination lister
  7. Choose either Windows default or your own temporary folder, such as RAM disk for maximum convenience selection survives even system reboot)
  8. Output formats: .cb7 (default, recommended), .cbr, .cbz
  9. For lots of files in queue, a file may be automatically deselected once this file conversion is complete (option)
  10. Import file may have folders structure depth at will, the program tries to get to the bottom of it to find where the image files actually are
  11. Provides logging so you can keep track via script log

SHOWCASE VIDEO

INSTALLATION

Use either provided button (.dcf) or attached VBScript code with dialog resource (please scroll down).
CBx to CBx Comic Book Convert Resize v1.50.dcf (31.3 KB)



WHY

...this program, since ComicRack can also do it?

Well, despite the fact that Directory Opus is more than ideal tool to do it, I wouldn't probably bother if I could find decent software to do it. The fact is that ComicRack has silently abrupted converting, due to some mysterious I/O errors. It might be that it didn't not like my computer being used whilst it was converting the files.

HISTORY

v1.00: 2017-01-28 Initial Release
v1.10: 2017-01-29 Ability to set custom temp folder such as RAM disk
v1.21: 2017-01-31 Ability to save TEMP folder for next script call (first official release)
v1.30: 2017-02-13
New user options:
(1) Do Not Resize
(2) Deselect file after conversion
Enforced error prevention:
(1) Make sure no protected files from deletion dialog pops-out
(2) Removes spaces before extension to prevent errors
v1.40: 2017-02-15
Added quality change option. Auto mode is now default.
v1.50: 2019-02-05 Small bugfix - Output format now correctly displays 7Z (.cb7)

METHOD

The script is programmed using VBScript over powerful Directory Opus objects. This is my first Directory Opus script. I believe it could be done better but I'm pretty satisfied with the final result, especially since it took me two days from v0.0 to v1.0. However, all suggestions and criticisms are more than welcomed. :slight_smile:

SCRIPT CODE

Is heavily commented. I believe it will help you great deal if you are DOpus script beginner like I was when I started with this little project.

CBx-TO-CBx SCRIPT CODE

@script VBScript
'--------------------------------------------------------------------------------
' CBx to CBx
' This script converts and resizes comic book files
' Includes versatile dialog for maximal user friendlines
' Date: 2017-01-31 
' Author: Dalibor Puljiz, Croatia
' Thanks:
' - Directory Opus developers for the greatest software
' - @Playful for providing great insight on DOpus object
'   through his first conversion script: 'cbr to cbz'
'   https://resource.dopus.com/t/button-cbr-to-cbz/23170
'Forum support:
' https://resource.dopus.com/t/button-comic-book-cbx-to-cbx-convert-resize/24719
'History:
' v1.00: 2017-01-28 Initial Release
' v1.10: 2017-01-29 Ability to set custom temp folder such as RAM disk
' v1.21: 2017-01-31 Ability to save TEMP folder for next script call (first official release)
' v1.30: 2017-02-13
'        New user options:
'         (1) Do Not Resize
'         (2) Deselect file after conversion
'        Enforced error prevention:
'         (1) Make sure no protected files from deletion dialog pops-out
'         (2) Removes spaces before extension to prevent errors
' v1.40: 2017-02-15
'        Added quality change option. Auto mode is now default.
' v1.50: 2019-02-05 Small bugfix - Output format now correctly displays 7Z (.cb7)
'--------------------------------------------------------------------------------


Option Explicit
Const WindowsFolder = 0
Const SystemFolder = 1
Const TemporaryFolder = 2


Function OnClick(ClickData)
Dim dlgO: Dim msgD
Dim ixList: Dim ixLabel: Dim ixXPos: Dim ixWPos: Dim ixHPos
Dim lngNewWidth: Dim lngNewHeight: Dim strResizeMode
Dim blnUseTempFolder: Dim strTmpF
Dim blnDeselectAfterConversion
Dim strUseSD
Dim fsT: Dim strOutFormat
Dim strTgtLst
Dim currentFile: Dim retF
Dim cmdDS


'Pickup where you left off

'Temp folder: Windows %Temp% folder recommended, most likely SSD disk anyway)
'However if you use some RAM disk (such as AMD RAM Disk), you may wish to keep it on

 Set fsT = CreateObject("Scripting.FileSystemObject")
 
 If DOpus.vars("CBxToCBxTempFolder").Exists Then
  strTmpF = DOpus.vars.get("CBxToCBxTempFolder")
 Else
  strTmpF = CStr(fsT.GetSpecialFolder(TemporaryFolder)) 
  DOpus.vars.set("CBxToCBxTempFolder")= strTmpF
  DOpus.vars("CBxToCBxTempFolder").Persist = True
 End If

 If DOpus.vars("CBxToCBxUseWindowsTemp").Exists Then
  blnUseTempFolder = CBool(DOpus.vars.get("CBxToCBxUseWindowsTemp"))
 Else
  blnUseTempFolder = True
  DOpus.vars.set("CBxToCBxUseWindowsTemp") = blnUseTempFolder
  DOpus.vars("CBxToCBxUseWindowsTemp").Persist = True
 End If



'Initialize dialog box using resource template
 Set dlgO = ClickData.Func.Dlg   
 dlgO.template = "dlgSetFileSize"
 dlgO.detach = True
 dlgO.Show

'Set defaults
'Resolution: 800×1280
 dlgO.Control("lstResolution").Value = 1
 lngNewHeight = 1280
 lngNewWidth  = 800
 strResizeMode = "Auto"
 dlgO.Control("chkOrientationMode").Value = 2  'Auto
 dlgO.Control("chkOrientationMode").Label = "Auto per image"
'Outptut format: cb7 and Auto dimension
 dlgO.Control("cbxOutputFormat").Value = 0   ' .cb7 (cbz)
 strOutFormat = ".cb7"
'Lister: Destination
 strUseSD = "destin"
 dlgO.Control("radUseSource").Value = False
 dlgO.Control("radUseDestination").Value  = True
'Temp section
 dlgO.Control("btnSelectFolder").Enabled = Not blnUseTempFolder
 dlgO.Control("tbxCustomTempFolder").Value = strTmpF
 dlgO.Control("radWindowsTemp").Value = blnUseTempFolder
 dlgO.Control("radCustomTempFolder").Value = Not blnUseTempFolder
 blnDeselectAfterConversion = False

'Keep running in detached mode so we can run events asynchronously 
 Do
  Set msgD = dlgO.GetMsg()
 'Preliminary pre-setup orientation modes, so later change may run smoothly
  If msgD.Control = "chkOrientationMode" Then
   Select Case dlgO.Control("chkOrientationMode").Value
    Case 0
     strResizeMode = "Landscape"
     dlgO.Control("chkOrientationMode").Label = "Force Landscape"
    Case 1
     strResizeMode = "Portrait"
     dlgO.Control("chkOrientationMode").Label = "Force Portrait"
    Case 2
     strResizeMode = "Auto"
     dlgO.Control("chkOrientationMode").Label = "Auto per image"	  
   End Select
  End If
 'Check everything
  Select Case msgD.Control
   Case "chkDoNotResize"
    dlgO.Control("chkOrientationMode").Enabled = Not (dlgO.Control("chkDoNotResize").Value)
    If dlgO.Control("chkDoNotResize").Value Then strResizeMode = "Do Not Resize"
   Case "lstResolution", "chkOrientationMode", "imgRWidth", "imgRHeight"
   'Get actual content label so to skip hard translate side-side coding 
    ixList =  dlgO.Control("lstResolution").Value
    ixLabel = dlgO.Control("lstResolution").GetItemAt(ixList).name      'ie: Android Tablet: 2560 × 1440
    If InStr(1,ixLabel,"Custom",1) = 0 Then
     dlgO.Control("imgRWidth").Enabled = False
	 dlgO.Control("imgRHeight").Enabled = False
     ixXPos = InStr(1,ixLabel,"×")                                      'W×H separated by ×
     ixWPos = InStrRev(ixLabel," ",ixXPos-2)                            'find first space backwards
     ixHPos = InStr(ixXPos+2,ixLabel," ")                               'find next space forward
     If ixHPos = 0 Then ixHPos = Len(ixLabel)                           'if not found assume max string length
     Select Case strResizeMode
      Case "Portrait", "Auto"
       lngNewHeight = Mid(ixLabel,ixWPos+1,(ixXPos-ixWPos-2))
       lngNewWidth  = Mid(ixLabel,ixXPos+2,(ixHPos-ixXPos-1))
      Case "Landscape"
       lngNewWidth  = Mid(ixLabel,ixWPos+1,(ixXPos-ixWPos-2))
       lngNewHeight = Mid(ixLabel,ixXPos+2,(ixHPos-ixXPos-1))
      End Select 
    Else
     dlgO.Control("imgRWidth").Enabled = True
	 dlgO.Control("imgRHeight").Enabled = True
     Select Case "strResizeMode"
      Case "Portrait", "Auto"
	   lngNewHeight = dlgO.Control("imgRWidth").Value
       lngNewWidth  = dlgO.Control("imgRHeight").Value
      Case "Landscape"
       lngNewWidth  = dlgO.Control("imgRWidth").Value
       lngNewHeight = dlgO.Control("imgRHeight").Value
     End Select
    End if
    dlgO.Control("tbxNotifySelected").Value = "Exporting to WH " & lngNewWidth & "×" & lngNewHeight & " (" & strResizeMode & ")"
  'Get other dialog options
   Case "radUseSource", "radUseDestination"
    Select Case msgD.Control 
	 Case "radUseSource":      strUseSD = "source"
     Case "radUseDestination": strUseSD = "destin"
	End Select 
   Case "cbxOutputFormat"
    Select Case dlgO.Control("cbxOutputFormat").Value
	 Case 0: strOutFormat = ".cb7"
	 Case 1: strOutFormat = ".cbz"
	 Case 2: strOutFormat = ".cbr"
	End Select
   Case "radWindowsTemp", "radCustomTempFolder"
	blnUseTempFolder = (msgD.Control = "radWindowsTemp")
    dlgO.Control("btnSelectFolder").Enabled = Not blnUseTempFolder
   Case "btnSelectFolder"
    Set retF = dlgO.folder("Select TEMP folder", strTmpF, True)
	If retF.result = True Then 
	 strTmpF = retF
	 dlgO.Control("tbxCustomTempFolder").Value = retF
	End If 
   Case "chkDeselectAsYouProgress"
    blnDeselectAfterConversion = dlgO.Control("chkDeselectAsYouProgress").Value
  End Select
 Loop While msgD

'If user set Cancel exit function
 If dlgO.Result = 0 Then Exit Function

'Proceed otherwise
 Select Case strUseSD 
  Case "source"
   strTgtLst = CStr(ClickData.Func.sourcetab.path)
  Case "destin"
   strTgtLst = Cstr(ClickData.Func.desttab.path)
 End Select



 If blnUseTempFolder Then strTmpF = CStr(fsT.GetSpecialFolder(TemporaryFolder))
 DOpus.vars.set("CBxToCBxUseWindowsTemp") = blnUseTempFolder
 If Not blnUseTempFolder Then DOpus.vars.set("CBxToCBxTempFolder")= strTmpF

 Set cmdDS = DOpus.Create.Command()
'cmdDS.deselect = True


'Log actions
 DOpus.Output("Target folder: " & strTgtLst)
 DOpus.Output("Export format: " & strOutFormat)
 DOpus.Output("Resolution WH: " & lngNewWidth & "×" & lngNewHeight & " mode: " & strResizeMode)


'Loop files
 For Each currentFile In clickData.func.sourcetab.selected_files
  cmdDS.Clear()
  cmdDS.ClearFiles()
  If ((LCase(currentFile.ext) = ".cbr") Or (LCase(currentFile.ext) = ".cbz") Or (LCase(currentFile.ext) = ".cb7")) Then
   DOpus.Output("Processing: " & currentFile.name_stem)
   Call CBR2CB7(currentFile, strTgtLst, strOutFormat, lngNewWidth, lngNewHeight, strResizeMode, strTmpF)
   If Right(currentFile.name_stem,1) = " " Then
    cmdDS.RunCommand("Rename FROM """ & currentFile.name &  """ TO """ & Trim(currentFile.name_stem) & currentFile.ext)
    currentFile.Update
   End If
   If blnDeselectAfterConversion Then cmdDS.RunCommand("Select """ & currentFile.name & """ DESELECT")
  Else
   Set dlgO = clickData.func.Dlg
   dlgO.buttons = "OK"
   dlgO.message = "Comic book file extension not recognized (" + currentFile.name + ")"
   dlgO.Show()
  End If
 Next

End Function



Function CBR2CB7(cFile, cFolder, expFmt, nWidth, nHeight, sRMode, sTempFolder) 
Dim cmdR7
Dim strLastFoundFolder: Dim strDestination: Dim dirHoldsFiles
Dim itmInspectFolder
Dim fso
Dim strT: Dim strTNmStm

'Extract files to temp folder
 Set cmdR7 = DOpus.Create.Command()
 cmdR7.Clear()
 strTNmStm = Trim(cFile.name_stem)
 strDestination = sTempFolder & "\" & strTNmStm 
 cmdR7.RunCommand("CreateFolder """ & strDestination & """ NOSEL")  
 cmdR7.SetDest(strDestination)
 cmdR7.AddFile(cFile)
 cmdR7.AddLine("Copy CLEARREADONLY=yes EXTRACT")
 cmdR7.Run()

'Find last folder that supposedly holds all the files
 Set dirHoldsFiles = DOpus.FSUtil.ReadDir(strDestination,True)
 strLastFoundFolder = strDestination
 Do While (Not dirHoldsFiles.complete)
  Set itmInspectFolder = dirHoldsFiles.Next
  If itmInspectFolder.is_dir Then
   strLastFoundFolder = itmInspectFolder.realpath
  End If
 Loop
'DOpus.Output(strLastFoundFolder)

'Resize
 cmdR7.Clear()
 cmdR7.ClearFiles()
 cmdR7.AddFilesFromFolder(strLastFoundFolder)
 Select Case sRMode 
  Case "Portrait"
   strT = "Image HEIGHT=" & nHeight 
  Case "Landscape"
   strT = "Image WIDTH=" & nWidth
  Case "Do Not Resize"
   strT = "Image "
  Case Else
   strT = "Image HEIGHT=" & nHeight & " WIDTH=" & nWidth
 End Select
 If sRMode <> "Do Not Resize" Then
  cmdR7.AddLine(strT & " QUALITY=90 PRESERVEASPECTRATIO NOENLARGE REPLACE HERE")
  cmdR7.Run()
 End If

'Compress
 cmdR7.Clear()
 cmdR7.ClearFiles()
 cmdR7.SetDest(cFolder)
 cmdR7.AddFilesFromFolder(strLastFoundFolder)
 Select Case expFmt
  Case ".cb7":  cmdR7.AddLine("Copy ARCHIVE=.7z  CREATEFOLDER=""" & strTNmStm + ".cb7""")
  Case ".cbz":  cmdR7.AddLine("Copy ARCHIVE      CREATEFOLDER=""" & strTNmStm + ".cbz""")
  Case ".cbr":  cmdR7.AddLine("Copy ARCHIVE=.rar CREATEFOLDER=""" & strTNmStm + ".cbr""")
 End Select 
 cmdR7.Run()

'Delete temp dir
 cmdR7.Clear()
 cmdR7.ClearFiles()
 cmdR7.AddFile(strDestination)
 cmdR7.AddLine("Delete NORECYCLE QUIET FORCE ")
 cmdR7.Run()

'Final cleanup
 dirHoldsFiles.Close()

End Function

Function IIf(blnExpression, vTrueResult, vFalseResult)
 If blnExpression Then
  IIf = vTrueResult
 Else
  IIf = vFalseResult
 End If
End Function

RESOURCES PART

<resources>
	<resource name="dlgSetFileSize" type="dialog">
		<dialog fontsize="8" height="250" lang="english" standard_buttons="ok,cancel" title="CBx-To-CBx Convert &amp; Resize" width="445">
			<control ellipsis="word" halign="left" height="8" name="static1" title="Set comic &amp;book downsampling resolution" type="static" width="149" x="9" y="7" />
			<control height="191" name="lstResolution" type="listbox" width="160" x="12" y="19">
				<contents>
					<item text="Android Tablet: 1024 × 600" />
					<item text="Android Tablet: 1280 × 800" />
					<item text="Android Tablet: 1920 × 1080 (Full HD)" />
					<item text="Android Tablet: 2048 × 1536" />
					<item text="Android Tablet: 2560 × 1440" />
					<item text="Android Tablet: 2560 × 1600" />
					<item text="Android Tablet: 3840 × 2160 (4k Ultra HD)" />
					<item text="Android Tablet: 7680 × 4320 (8k)" />
					<item text="Android Phone: 320 × 480" />
					<item text="Android Phone: 480 × 800" />
					<item text="Android Phone: 480 × 854" />
					<item text="Android Phone: 540 × 960" />
					<item text="Android Phone: 1280 × 720 (HD 720p)" />
					<item text="Android Phone: 1920 × 1080 (Full HD 1080p)" />
					<item text="Android Phone: 3840 × 2160 (4k Ultra HD)" />
					<item text="iPhone5: 640 × 1136" />
					<item text="iPhone7: 750 × 1334" />
					<item text="iPhone7+: 1242 × 2208" />
					<item text="iPad Mini: 1536 × 2048" />
					<item text="iPad Air: 1536 × 2048" />
					<item text="iPad Pro: 2048 × 2732" />
					<item text="Use custom width and height" />
				</contents>
			</control>
			<control halign="left" height="12" name="tbxNotifySelected" readonly="yes" title="Please select export resolution" type="edit" width="160" x="12" y="211" />
			<control halign="left" height="8" name="static9" title="Resize orientation mode" type="static" width="84" x="183" y="16" />
			<control height="10" name="chkDoNotResize" title="Do not resize, only repack" type="check" width="103" x="184" y="29" />
			<control height="10" indeterminate="yes" name="chkOrientationMode" title="Orientation Mode" tristate="yes" type="check" width="100" x="184" y="41" />
			<control halign="left" height="40" name="static5" title="Makes sure better size is\n preserved with aspect ratio\n kept intact (options: Auto,\n Portrait: keep height,\n Landscape: keep width)." type="static" width="100" x="198" y="54" />
			<control halign="left" height="8" name="static6" title="Export comic book to:" type="static" width="79" x="325" y="16" />
			<control height="10" name="radUseSource" title="Source lister" type="radio" width="55" x="331" y="28" />
			<control checked="yes" height="10" name="radUseDestination" title="Destination lister" type="radio" width="74" x="331" y="40" />
			<control halign="left" height="10" name="static4" title="Select custom size" type="static" width="69" x="184" y="111" />
			<control halign="center" height="8" name="static2" title="Wi&amp;dth" type="static" width="26" x="188" y="125" />
			<control enable="no" halign="center" height="12" name="imgRWidth" title="1280" type="edit" width="28" x="220" y="123" />
			<control halign="center" height="8" name="static3" title="Hei&amp;ght" type="static" width="26" x="188" y="139" />
			<control enable="no" halign="center" height="12" name="imgRHeight" title="800" type="edit" width="28" x="220" y="137" />
			<control halign="left" height="8" name="static7" title="Output format" type="static" width="51" x="325" y="66" />
			<control height="40" name="cbxOutputFormat" type="combo" width="51" x="329" y="76">
				<contents>
					<item text="7Z  (.cb7)" />
					<item text="ZIP (.cbz)" />
					<item text="RAR (.cbr)" />
				</contents>
			</control>
			<control halign="left" height="8" name="static9" title="Temporary folder" type="static" width="58" x="184" y="167" />
			<control checked="yes" group="yes" height="10" name="radWindowsTemp" title="Windows TEMP folder" type="radio" width="86" x="190" y="178" />
			<control height="10" name="radCustomTempFolder" type="radio" width="13" x="190" y="190" />
			<control halign="left" height="12" name="tbxCustomTempFolder" readonly="yes" title="Select Your Temp Folder" type="edit" width="213" x="203" y="189" />
			<control enable="no" height="14" name="btnSelectFolder" title="..." type="button" width="16" x="420" y="179" />
			<control height="10" name="chkDeselectAsYouProgress" title="Progressively deselect file after conversion" type="check" width="158" x="190" y="209" />
			<control halign="center" height="12" name="tbxQuality" readonly="yes" title="75" type="edit" width="21" x="399" y="122" />
			<control halign="left" height="8" name="static10" title="Quality %" type="static" width="38" x="325" y="111" />
			<control height="10" name="chkEnforceQuality" title="Change to max" type="check" width="65" x="330" y="123" />
			<control halign="left" height="8" name="static11" title="%" type="static" width="7" x="424" y="124" />
		</dialog>
	</resource>
</resources>

BUGS

This program has been extensively tested against my own (large) comic book collection. Currently, all known bugs have been squashed.

CREDITS

  1. Directory Opus developers for the greatest software and extremely responsive help
  2. @Playful for providing great insight on DOpus object through his first conversion script: 'cbr to cbz', Button: cbr to cbz
3 Likes

Hi, there.

I've got a load of comics from various Humble Bundles and some of them have white borders around the pages, which is annoying when you're looking at a double page spread. I've was thinking about trying to knock up something to unzip the file, crop all of the images to a preset size and zip them back up again, but I'm probably never going to get around to it. Would it be something you'd consider adding to your script?

Cool idea, but I'm afraid that's not too simple, as we would need first some app that is able to enter the content, meaning - intelligently and automatically crop around the edges.

ImageMagick can do it, with optional fuzziness for JPEG compression:

https://www.imagemagick.org/discourse-server/viewtopic.php?t=15675

1 Like

Personally, I'd be happy with passing simple top-left, bottom-right coords: the files I've been looking at seem to be consistent in border width. Anyway, the layout often leaves whitespace around the panels, which would make it harder to determine where to crop using code, I assume.

ImageMagick has an argument that makes it find the borders automatically, based on pixel colors.

Thx for your script.
Is it possible to update your script to add a new option : % of reduction instead of fixed standard size ?

i've previously made a DOS script but your solution is so more elegant !

7z x %1 -o%1".temp"
cd %1.temp\
nconvert.exe -out jpeg -ratio -rtype lanczos -resize 75%%%% 75%%  -autocontrast -eedge 1 -q 85 -overwrite *.*
rmdir __MACOSX /q /S
FOR /D /R %%a IN (*) DO nconvert.exe -out jpeg -ratio -rtype lanczos -resize 75%%%% 75%%  -autocontrast -eedge 1 -q 85 -overwrite "%%~sa"\*.*
del *.png
cd ..
7z a -tzip %1.cbz %1.temp -mx=0
rmdir %1.temp /s/q

I guess so, it's been awhile since I created it, but I'll have a look in a couple of days. The time is running short these days. :slight_smile:

Thanks to the comments of your code, I decided to start the programming.
The last time I wrote a program was 22 years ago in C or Fortran and I've never used object programming language.
But after 3 weeks of heavy documentation reading I've obtained all that I wanted.
I guess it could be written better (I have myself rewrite lot of lines that I wrote the first week)
So, let me introduce you

Comic Book CBx-To-CBx Convert & Resize v2 !!!

image

FEATURES

+all of V1.4

  • option for a custom ratio transformation (instead of standard height and weight) and quality
  • option to create a backup file (with choice of a prefix and/or suffix)
  • option to check if extension is in keeping with the inside format of the archive and rename it (I had lot of cbz that were rar file or cbr that were zip file, and dopus was not handling correctly their bad name)
  • option to make compression only if the average image size in the archive is over a custom size (I've got 300 Mo cbr with only 50 pages...)
  • Selected files can be selected with "Flat view" activated. The compressed file will be on the same directory as original (if destination "source" is chosen)
  • Configuration saved between 2 sessions
  • Changed the way that conversion is called : before, if the original file contains subfolder the result have only the last alphabetic folder converted. Now, they are all converted.
  • Lots of logs added
  • bug fix on custom widht and height
  • minor bug fix when the output format was cb7

NB: If you choose cbr as destination format, you MUST have winrar installed on your platform and you must have activated the rar plugin in Dopus (Preferences / Zip & Other Archives / Archive and VFS Plugins)

I've been heavily using it for one month, and I've not found anymore bugs.

I hope you will find this dialogbox useful.

INSTALLATION

Use either provided button (.dcf) or attached VBScript code with dialog resource (please scroll down).
CBx to CBX V2.1.1.dcf (59.3 KB)

I've made a beautiful icon :slight_smile: : CustomCbx

The script:

@script VBScript
'--------------------------------------------------------------------------------
' CBx to CBx
' This script converts and resizes comic book files
' Includes versatile dialog for maximal user friendlines
' Date: 2017-01-31 
' Author: Dalibor Puljiz, Croatia
' ' Thanks:
' - Directory Opus developers for the greatest software
' - @Playful for providing great insight on DOpus object
'   through his first conversion script: 'cbr to cbz'
'   http://resource.dopus.com/viewtopic.php?f=35&t=27206
'Forum support:
' https://resource.dopus.com/t/button-comic-book-cbx-to-cbx-convert-resize/24719
'History:
' v1.0: 2017-01-28 Initial Release
' v1.1: 2017-01-29 Ability to set custom temp folder such as RAM disk
' v1.2: 2017-01-31 Ability to save TEMP folder for next script call (first official release)
' v1.3: 2017-02-13
'       New user options:
'        (1) Do Not Resize
'        (2) Deselect file after conversion
'       Enforced error prevention:
'        (1) Make sure no protected files from deletion dialog pops-out
'        (2) Removes spaces before extension to prevent errors
' v1.4: 2017-02-14
'       Added quality change option, Auto mode as default
' v2.0: 2019-01-18
'		Evolution by Olivier Evesque, France
'		Added option for a custom ratio transformation (instead of standard height and weight) and quality
'		Added option to create a backup file (with choice of a prefix and/or suffix)
'		Added option to check if extension is in keeping with the inside format of the archive and rename it
'		Added option to make compression only if the average image size in the archive is over a custom size
'		Selected files can be selected with "Flat view" activated. The compressed file will be on the same directory as original (if destination "source" is chosen)
'		Changed the way that conversion is called : before, if the original file contains subfolder the result have only the last alphabetic folder converted. Now, they are all converted.
'	    Lots of log added
'		bug fix on custom widht and height
'		minor bug fix when the output format was cb7
'		If you choose cbr as destination format, you MUST have winrar installed on your platform and you must have activated the rar plugin in Dopus (Preferences / Zip & Other Archives / Archive and VFS Plugins)
'--------------------------------------------------------------------------------


Option Explicit
Const WindowsFolder = 0
Const SystemFolder = 1
Const TemporaryFolder = 2


Function OnClick(ClickData)
Dim dlgO: Dim msgD
Dim ixList: Dim ixLabel: Dim ixXPos: Dim ixWPos: Dim ixHPos
Dim lngNewWidth: Dim lngNewHeight: Dim strResizeMode
Dim blnUseTempFolder: Dim strTmpF
Dim blnDeselectAfterConversion
Dim strUseSD
Dim fsT: Dim strOutFormat
Dim strTgtLst: Dim strDirTgt
Dim currentFile: Dim retF
Dim cmdDS
Dim strRatio: Dim StrQuality
Dim StrPrefix: Dim StrSuffix
Dim fso, f
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim header
Dim CountedRenamedFiles
dim backup
CountedRenamedFiles=0



'Initialize dialog box using resource template
 Set dlgO = ClickData.Func.Dlg   
 dlgO.template = "dlgSetFileSize"
 dlgO.detach = True
 dlgO.Show

'typable field will be saved only after cliking OK
  DOpus.vars("CBxToCBxCustomRatio").Persist = False
  DOpus.vars("CBxToCBxCustomQuality").Persist = False
  DOpus.vars("CBxToCBxCustomPrefix").Persist = False
  DOpus.vars("CBxToCBxCustomSuffix").Persist = False
  DOpus.vars("CBxToCBxCustomAvgSize").Persist = False

'Set defaults
'Resolution: Custom Ratio
 dlgO.Control("lstResolution").Value = 22 'Custom Ratio
 lngNewHeight = 1280
 lngNewWidth  = 800
 strResizeMode = "Auto"
 dlgO.Control("chkOrientationMode").Value = 2  'Auto
 dlgO.Control("chkOrientationMode").Label = "Auto per image"
'Outptut format: cbz and Auto dimension
 dlgO.Control("cbxOutputFormat").Value = 1   ' .cbz (cbz)
 strOutFormat = ".cbz"
'Lister: Destination
 strUseSD = "source"
 dlgO.Control("radUseSource").Value = True
 dlgO.Control("radUseDestination").Value  = False
'Temp section
 dlgO.Control("btnSelectFolder").Enabled = Not blnUseTempFolder
 dlgO.Control("tbxCustomTempFolder").Value = strTmpF
 dlgO.Control("radWindowsTemp").Value = blnUseTempFolder
 dlgO.Control("radCustomTempFolder").Value = Not blnUseTempFolder
 blnDeselectAfterConversion = False




'Pickup where you left off

'Temp folder: Windows %Temp% folder recommended, most likely SSD disk anyway)
'However if you use some RAM disk (such as AMD RAM Disk), you may wish to keep it on

 Set fsT = CreateObject("Scripting.FileSystemObject")
 
 If DOpus.vars("CBxToCBxTempFolder").Exists Then
  strTmpF = DOpus.vars.get("CBxToCBxTempFolder")
 Else
  strTmpF = CStr(fsT.GetSpecialFolder(TemporaryFolder)) 
  DOpus.vars.set("CBxToCBxTempFolder")= strTmpF
  DOpus.vars("CBxToCBxTempFolder").Persist = True
 End If

 If DOpus.vars("CBxToCBxUseWindowsTemp").Exists Then
  blnUseTempFolder = CBool(DOpus.vars.get("CBxToCBxUseWindowsTemp"))
 Else
  blnUseTempFolder = True
  DOpus.vars.set("CBxToCBxUseWindowsTemp") = blnUseTempFolder
  DOpus.vars("CBxToCBxUseWindowsTemp").Persist = True
 End If

 If DOpus.vars("CBxToCBxCustomRatio").Exists Then
  dlgO.Control("tbxRatio").value=DOpus.vars("CBxToCBxCustomRatio")
 end if

 If DOpus.vars("CBxToCBxCustomQuality").Exists Then
  dlgO.Control("tbxQuality").value=DOpus.vars("CBxToCBxCustomQuality")
 end if

 If DOpus.vars("CBxToCBxCustomPrefix").Exists Then
  dlgO.Control("tbxPrefix").value=DOpus.vars("CBxToCBxCustomPrefix")
 end if

 If DOpus.vars("CBxToCBxCustomSuffix").Exists Then
  dlgO.Control("tbxSuffix").value=DOpus.vars("CBxToCBxCustomSuffix")
 end if

 If DOpus.vars("CBxToCBxCustomAvgSize").Exists Then
  dlgO.Control("TbxMaxAvgSize").value=DOpus.vars("CBxToCBxCustomAvgSize")
 end if



'Keep running in detached mode so we can run events asynchronously 
 Do
  Set msgD = dlgO.GetMsg()
 'Preliminary pre-setup orientation modes, so later change may run smoothly
  If msgD.Control = "chkOrientationMode" Then
   Select Case dlgO.Control("chkOrientationMode").Value
    Case 0
     strResizeMode = "Landscape"
     dlgO.Control("chkOrientationMode").Label = "Force Landscape"
    Case 1
     strResizeMode = "Portrait"
     dlgO.Control("chkOrientationMode").Label = "Force Portrait"
    Case 2
     strResizeMode = "Auto"
     dlgO.Control("chkOrientationMode").Label = "Auto per image"	  
   End Select
  End If
 'Check everything
  Select Case msgD.Control
   Case "chkDoNotResize"
    dlgO.Control("chkOrientationMode").Enabled = Not (dlgO.Control("chkDoNotResize").Value)
	dlgO.Control("ChkAutoCompress").value = Not (dlgO.Control("chkDoNotResize").Value)
    If dlgO.Control("chkDoNotResize").Value Then strResizeMode = "Do Not Resize"
   Case "lstResolution", "chkOrientationMode", "imgRWidth", "imgRHeight"
   'Get actual content label so to skip hard translate side-side coding 
    ixList =  dlgO.Control("lstResolution").Value
    ixLabel = dlgO.Control("lstResolution").GetItemAt(ixList).name      'ie: Android Tablet: 2560 × 1440
    If InStr(1,ixLabel,"Custom",1) = 0 Then
     dlgO.Control("imgRWidth").Enabled = False
	 dlgO.Control("imgRHeight").Enabled = False
	 dlgO.Control("tbxRatio").Enabled = False
	 dlgO.Control("tbxQuality").Enabled = False
	 strRatio=0
     ixXPos = InStr(1,ixLabel,"×")                                      'W×H separated by ×
     ixWPos = InStrRev(ixLabel," ",ixXPos-2)                            'find first space backwards
     ixHPos = InStr(ixXPos+2,ixLabel," ")                               'find next space forward
     If ixHPos = 0 Then ixHPos = Len(ixLabel)                           'if not found assume max string length
     Select Case strResizeMode
      Case "Portrait", "Auto"
       lngNewHeight = Mid(ixLabel,ixWPos+1,(ixXPos-ixWPos-2))
       lngNewWidth  = Mid(ixLabel,ixXPos+2,(ixHPos-ixXPos-1))
      Case "Landscape"
       lngNewWidth  = Mid(ixLabel,ixWPos+1,(ixXPos-ixWPos-2))
       lngNewHeight = Mid(ixLabel,ixXPos+2,(ixHPos-ixXPos-1))
     End Select 
	 dlgO.Control("tbxNotifySelected").Value = "Exporting to WH " & lngNewWidth & "×" & lngNewHeight & " (" & strResizeMode & ")"  
	Elseif  InStr(1,ixLabel,"Custom ratio",1) <> 0 Then 
	 dlgO.Control("imgRWidth").Enabled = False
	 dlgO.Control("imgRHeight").Enabled = False
	 dlgO.Control("tbxRatio").Enabled = True
	 dlgO.Control("tbxQuality").Enabled = True
	 strRatio = dlgO.Control("tbxRatio").Value
	 StrQuality= dlgO.Control("tbxQuality").Value
	 dlgO.Control("tbxNotifySelected").Value = "Exporting to ratio  " & strRatio & " and quality " & StrQuality
	Else  'this test is for custom Width and Height
     dlgO.Control("imgRWidth").Enabled = True
	 dlgO.Control("imgRHeight").Enabled = True
	 dlgO.Control("tbxRatio").Enabled = False
	 dlgO.Control("tbxQuality").Enabled = False
	 strRatio=0
	 StrQuality=90
     Select Case strResizeMode
      Case "Portrait", "Auto"
	   lngNewHeight = dlgO.Control("imgRWidth").Value
       lngNewWidth  = dlgO.Control("imgRHeight").Value
      Case "Landscape"
       lngNewWidth  = dlgO.Control("imgRWidth").Value
       lngNewHeight = dlgO.Control("imgRHeight").Value
     End Select
	 dlgO.Control("tbxNotifySelected").Value = "Exporting to WH " & lngNewWidth & "×" & lngNewHeight & " (" & strResizeMode & ")"
    End if

  'Get other dialog options
   Case "radUseSource", "radUseDestination"
    Select Case msgD.Control 
	 Case "radUseSource":      strUseSD = "source"
     Case "radUseDestination": strUseSD = "destin"
	End Select 
   Case "cbxOutputFormat"
    Select Case dlgO.Control("cbxOutputFormat").Value
	 Case 0: strOutFormat = ".cb7"
	 Case 1: strOutFormat = ".cbz"
	 Case 2: strOutFormat = ".cbr"
	End Select
   Case "radWindowsTemp", "radCustomTempFolder"
	blnUseTempFolder = (msgD.Control = "radWindowsTemp")
    dlgO.Control("btnSelectFolder").Enabled = Not blnUseTempFolder
   Case "btnSelectFolder"
    Set retF = dlgO.folder("Select TEMP folder", strTmpF, True)
	If retF.result = True Then 
	 strTmpF = retF
	 dlgO.Control("tbxCustomTempFolder").Value = retF
	End If 
   Case "chkDeselectAsYouProgress"
    blnDeselectAfterConversion = dlgO.Control("chkDeselectAsYouProgress").Value
	
   'get info on typable fields
	case "tbxRatio", "tbxQuality"
  	  StrRatio = dlgO.Control("tbxRatio").Value
	  StrQuality= dlgO.Control("tbxQuality").Value
	  dlgO.Control("tbxNotifySelected").Value = "Exporting to ratio  " & strRatio & " and quality " & StrQuality
	 
	case "tbxPrefix", "tbxSuffix"
	  StrPrefix= dlgO.Control("tbxPrefix").Value
	  StrSuffix= dlgO.Control("tbxSuffix").Value

	case "TbxMaxAvgSize"
	  DOpus.vars.set("CBxToCBxCustomAvgSize")= dlgO.Control("TbxMaxAvgSize").Value 'I should have used a variable :-(
	  
  end select
	

  if Msgd.control="ChkAutoCompress" then  'Click on Checkbox Compress only if ...
  	dlgO.Control("TbxMaxAvgSize").Enabled = not dlgO.Control("TbxMaxAvgSize").Enabled
  End if
  if Msgd.control="chkBackup" then 'Click on backup file Compress only if ...
  	dlgO.Control("tbxSuffix").Enabled = not dlgO.Control("tbxSuffix").Enabled
	dlgO.Control("tbxPrefix").Enabled = not dlgO.Control("tbxPrefix").Enabled
  end if
 Loop While msgD


 

'If user set Cancel exit function
 If dlgO.Result = 0 Then
  Exit Function
 Else
 'Saving for next session the typable field. 
  DOpus.vars.set("CBxToCBxCustomRatio")= strRatio
  DOpus.vars.set("CBxToCBxCustomQuality")= strQuality
  DOpus.vars.set("CBxToCBxCustomPrefix")= StrPrefix	 
  DOpus.vars.set("CBxToCBxCustomSuffix")= StrSuffix	 	
  DOpus.vars("CBxToCBxCustomRatio").Persist = True
  DOpus.vars("CBxToCBxCustomQuality").Persist = True
  DOpus.vars("CBxToCBxCustomPrefix").Persist = True	
  DOpus.vars("CBxToCBxCustomSuffix").Persist = True	
  DOpus.vars("CBxToCBxCustomAvgSize").Persist = True
 End if


'Proceed otherwise
 Select Case strUseSD 
  Case "source"
   strTgtLst = CStr(ClickData.Func.sourcetab.path)
  Case "destin"
   strTgtLst = Cstr(ClickData.Func.desttab.path)
  End Select



 If blnUseTempFolder Then strTmpF = CStr(fsT.GetSpecialFolder(TemporaryFolder))
 DOpus.vars.set("CBxToCBxUseWindowsTemp") = blnUseTempFolder
 If Not blnUseTempFolder Then DOpus.vars.set("CBxToCBxTempFolder")= strTmpF

 Set cmdDS = DOpus.Create.Command()
'cmdDS.deselect = True


'Log actions
 Dopus.output ("***************************************")
 DOpus.Output("Target folder: " & strTgtLst)
 DOpus.Output("Export format: " & strOutFormat)
 If strRatio = 0 then
  DOpus.Output("Export Resolution WH: " & lngNewWidth & "×" & lngNewHeight & " mode: " & strResizeMode)
 else
  DOpus.Output("Export with Ratio: " & StrRatio & " and quality " & StrQuality) 
 End if
 If dlgO.control("chkBackup").value then
  Dopus.output ("Make a Backup of converted file")
  backup=true
 Else
  Dopus.output ("Overwriting existing file")
  backup=false
 End if
 If dlgO.control("ChkAutoCompress").value then
   Dopus.output ("Convert file only if Avg size is bigger than " & dlgO.Control("TbxMaxAvgSize").Value & " Mo" )
 Else
  Dopus.output ("Convert all files")
 End if
 


'Loop files
 For Each currentFile In clickData.func.sourcetab.selected_files
 'we're checking if the extension is compatible with the internal compress algorithm, If not, we are renaming file
 If dlgO.control("chkCheckName").value then
 		If clickData.func.sourcetab.selected.count = 0 Then
  		 DOpus.Output "  Aucune selection"
 		Else
   		 Set fso = CreateObject("Scripting.FileSystemObject")
   		 Set f = fso.OpenTextFile(currentFile.RealPath, ForReading)
		 header=lcase(f.Read(2))
   		 f.close
		 if (lcase(currentfile.ext)=".cbz" and header="pk") or (lcase(currentfile.ext)=".cbr" and header="ra") or (lcase(currentfile.ext)=".cb7" and header="7z") then
		 'Dopus.output "File " & currentFile.RealPath & " have a correct extension"
		 else
		  Dopus.output " File  " & currentFile.RealPath & " have NOT a correct extension"
		  CountedRenamedFiles= CountedRenamedFiles +1
		  select case header
		   case "pk"
		  ' cmdDS.RunCommand("Rename PATTERN=* FROM " & currentFile.name  &  " TO " & currentFile.name_stem & ".cbz" )
		   Dopus.output " -->Rename """  & currentfile.path & "\" & currentFile.name & """ TO """ & currentfile.path & "\" & currentFile.name_stem & ".cbz"
		   cmdDS.RunCommand("Rename """  & currentfile.path & "\" & currentFile.name & """ TO """ & currentfile.path & "\" & currentFile.name_stem  & ".cbz" )
		   case "ra"
		   Dopus.output " -->Rename """  & currentfile.path & "\" & currentFile.name & """ TO """ & currentfile.path & "\" & currentFile.name_stem & ".cbr"
		   cmdDS.RunCommand("Rename """  & currentfile.path & "\" & currentFile.name & """ TO """ & currentfile.path & "\" & currentFile.name_stem  & ".cbr" )
		   case "7z"
		   Dopus.output " -->Rename """  & currentfile.path & "\" & currentFile.name & """ TO """ & currentfile.path & "\" & currentFile.name_stem & ".cb7"
		   cmdDS.RunCommand("Rename """  & currentfile.path & "\" & currentFile.name & """ TO """ & currentfile.path & "\" & currentFile.name_stem  & ".cb7" )
		   case else
		   Dopus.output (" -->" & currentfile.name & " is not recognized as a comic book")
		  end Select
		 End If 
		 End If
 Else
  cmdDS.Clear()
  cmdDS.ClearFiles()
 	 If ((LCase(currentFile.ext) = ".cbr") Or (LCase(currentFile.ext) = ".cbz") Or (LCase(currentFile.ext) = ".cb7")) Then
 		DOpus.Output(" Processing: " & currentFile.name_stem)
		Select Case strUseSD 
  			Case "source"
			   strTgtLst = CStr(currentfile.path)  ' source path have been previously initialized wut it can change if you have selected files on different subdirectory on a lister with "Flatview"
  			Case "destin"
			   strTgtLst = Cstr(ClickData.Func.desttab.path)
 		 End Select
			 
		If dlgO.control("ChkAutoCompress").value then 'we are checking if the size of the file divided by then number of files is greater than the wanted value.
		   'on va compter les fichiers
	       If cdbl((currentFile.size.cy*10000/(1024^2))/FileCountRecursive(currentFile)) >= cdbl(replace(dlgO.Control("TbxMaxAvgSize").Value,".",",")) Then	 'Cdbl is for convertit txt to number, and the replace is to accept different number format (1,2 ou 1.2)	   
		    dopus.output "  File " & currentFile & " have a size of " & currentFile.size.cy*10000/(1024^2) & "and have "& FileCountRecursive(currentFile) & " files so  " & (currentFile.size.cy*10000/(1024^2))/FileCountRecursive(currentFile) & " Mo on average"
		
			
		    Call CBR2CB7(currentFile, strTgtLst, strOutFormat, lngNewWidth, lngNewHeight, strResizeMode, strTmpF, strRatio, strQuality, StrPrefix, strSuffix, backup)
   		    If Right(currentFile.name_stem,1) = " " Then
    	   	 cmdDS.RunCommand("Rename FROM """ & currentFile.name &  """ TO """ & Trim(currentFile.name_stem) & currentFile.ext)
    	   	 currentFile.Update
   		    end If
   		    If blnDeselectAfterConversion Then 
		    cmdDS.RunCommand("Select """ & currentFile.name & """ DESELECT")
		    End If
		   Else
			  dopus.output "  File " & currentFile & " have " & FileCountRecursive(currentFile) & " file and it size is " & currentFile.size.cy*10000/(1024^2) & " so  " & (currentFile.size.cy*10000/(1024^2))/FileCountRecursive(currentFile) & " Mo on average -->No convertion needed"
		   End if
		Else
		 	Call CBR2CB7(currentFile, strTgtLst, strOutFormat, lngNewWidth, lngNewHeight, strResizeMode, strTmpF, strRatio, strQuality, StrPrefix, strSuffix, backup)
   		    If Right(currentFile.name_stem,1) = " " Then
    	   	 cmdDS.RunCommand("Rename FROM """ & currentFile.name &  """ TO """ & Trim(currentFile.name_stem) & currentFile.ext)
    	   	 currentFile.Update
   		    end If
   		    If blnDeselectAfterConversion Then 
		    cmdDS.RunCommand("Select """ & currentFile.name & """ DESELECT")
		    Dopus.output "on compresse dans tout les cas"
			End if
		End if
  	Else
   	 Set dlgO = clickData.func.Dlg
   	 dlgO.buttons = "OK"
   	 dlgO.message = "Comic book file extension not recognized (" + currentFile.name + ")"
   	 dlgO.Show()
  	End If
 End If
 Next

 If dlgO.control("chkCheckName").value then 
 Dopus.output CountedRenamedFiles & " files have been renamed"
 End if

End Function



Function CBR2CB7(cFile, cFolder, expFmt, nWidth, nHeight, sRMode, sTempFolder, sRatio, sQuality, sPrefix, sSuffix, backup) 
Dim cmdR7
Dim strLastFoundFolder: Dim strDestination: Dim dirHoldsFiles
Dim itmInspectFolder
Dim fso
Dim strT: Dim strTNmStm


'Extract files to temp folder
 Set cmdR7 = DOpus.Create.Command()
 cmdR7.Clear()
 strTNmStm = Trim(cFile.name_stem)
 strDestination = sTempFolder & "\" & strTNmStm 
 cmdR7.RunCommand("CreateFolder """ & strDestination & """ NOSEL")  
 cmdR7.SetDest(strDestination)
 cmdR7.AddFile(cFile)
 cmdR7.AddLine("Copy CLEARREADONLY=yes EXTRACT")
 cmdR7.Run()
 cmdR7.Clear()
'Make a Backup of the original file, with suffix and/or prefix
 If backup then
  DOpus.Output("  Renaming  """ & cFile.path & "\" & cFile.name & """ TO """ & cFile.path & "\" & sPrefix & strTNmStm & sSuffix & cfile.ext &  """" )
  cmdR7.RunCommand("Rename """ & cFile.path & "\" & cFile.name & """ TO """ & cFile.path & "\"  & sPrefix & strTNmStm & sSuffix & cfile.ext & """")
 End if




'Find last folder that supposedly holds all the files
 Set dirHoldsFiles = DOpus.FSUtil.ReadDir(strDestination,"rl")
 strLastFoundFolder = strDestination
 'first convert image in the principal temp directory
 ConvertFileInDirectory strDestination, nHeight, nWidth,sRMode, sQuality, sRatio
 Do While (Not dirHoldsFiles.complete) 'then convert image inside each subfolder
  Set itmInspectFolder = dirHoldsFiles.Next
  If itmInspectFolder.is_dir Then
   strLastFoundFolder = itmInspectFolder.realpath
   ConvertFileInDirectory strLastFoundFolder, nHeight, nWidth, sRMode, sQuality, sRatio
  End If ' end condition if this a folder
 Loop
'DOpus.Output(strLastFoundFolder)


'Compress
 cmdR7.Clear()
 cmdR7.ClearFiles()
 cmdR7.SetDest(cFolder)
' cmdR7.AddFilesFromFolder(strLastFoundFolder)
 cmdR7.AddFilesFromFolder(strDestination)
 Select Case expFmt
  Case ".cb7":  cmdR7.AddLine("Copy ARCHIVE=.7z  CREATEFOLDER=""" & strTNmStm + ".cb7""")
  Case ".cbz":  cmdR7.AddLine("Copy ARCHIVE      CREATEFOLDER=""" & strTNmStm + ".cbz""")
  Case ".cbr":  cmdR7.AddLine("Copy ARCHIVE=.rar CREATEFOLDER=""" & strTNmStm + ".cbr""")
 End Select 
 cmdR7.Run()

'Delete temp dir
 cmdR7.Clear()
 cmdR7.ClearFiles()
 cmdR7.AddFile(strDestination)
 cmdR7.AddLine("Delete NORECYCLE QUIET FORCE ")
 cmdR7.Run()

'Final cleanup
 dirHoldsFiles.Close()

End Function

Function ConvertFileInDirectory (folder, Height, Width, srMode, sQuality, sRatio)
dim cmdConvert
dim strT
'Resize
Set cmdConvert = DOpus.Create.Command()
   cmdConvert.Clear()
   cmdConvert.ClearFiles()
   cmdConvert.AddFilesFromFolder(folder)
   Select Case sRMode 
    Case "Portrait"
     strT = "Image HEIGHT=" & Height 
    Case "Landscape"
     strT = "Image WIDTH=" & Width
    Case "Do Not Resize"
     strT = "Image "
    Case Else
     strT = "Image HEIGHT=" & Height & " WIDTH=" & Width
   End Select
   If sRMode <> "Do Not Resize" Then
    cmdConvert.AddLine(strT & " QUALITY=90 PRESERVEASPECTRATIO NOENLARGE REPLACE HERE")
    if sRatio<>0 then
    cmdConvert.Clear()
    cmdConvert.Addline ("Image CONVERT QUALITY=" & sQuality & " PERCENT="& sRatio & " REPLACE HERE" )
    end if
   cmdConvert.Run()
   End If
End function


function FileCountRecursive(filePath) 
  dim filecount:	dim folderEnum: 	dim folderItem
  Set folderEnum = DOpus.FSUtil.ReadDir(filePath,"r")
  Do while (not folderEnum.complete)
		set folderItem = folderEnum.Next
		if not(folderItem.is_dir) then
			fileCount=filecount+1
		end if
  loop
  FileCountRecursive= fileCount
End function

The ressource:

<resources>
	<resource name="dlgSetFileSize" type="dialog">
		<dialog fontsize="8" height="286" lang="english" standard_buttons="ok,cancel" title="CBx-To-CBx Convert &amp; Resize" width="445">
			<control ellipsis="word" halign="left" height="8" name="static1" title="Set comic &amp;book downsampling resolution" type="static" width="149" x="9" y="7" />
			<control height="191" name="lstResolution" type="listbox" width="160" x="12" y="19">
				<contents>
					<item text="Android Tablet: 1024 × 600" />
					<item text="Android Tablet: 1280 × 800" />
					<item text="Android Tablet: 1920 × 1080 (Full HD)" />
					<item text="Android Tablet: 2048 × 1536" />
					<item text="Android Tablet: 2560 × 1440" />
					<item text="Android Tablet: 2560 × 1600" />
					<item text="Android Tablet: 3840 × 2160 (4k Ultra HD)" />
					<item text="Android Tablet: 7680 × 4320 (8k)" />
					<item text="Android Phone: 320 × 480" />
					<item text="Android Phone: 480 × 800" />
					<item text="Android Phone: 480 × 854" />
					<item text="Android Phone: 540 × 960" />
					<item text="Android Phone: 1280 × 720 (HD 720p)" />
					<item text="Android Phone: 1920 × 1080 (Full HD 1080p)" />
					<item text="Android Phone: 3840 × 2160 (4k Ultra HD)" />
					<item text="iPhone5: 640 × 1136" />
					<item text="iPhone7: 750 × 1334" />
					<item text="iPhone7+: 1242 × 2208" />
					<item text="iPad Mini: 1536 × 2048" />
					<item text="iPad Air: 1536 × 2048" />
					<item text="iPad Pro: 2048 × 2732" />
					<item text="Use custom width and height" />
					<item text="Use custom ratio" />
				</contents>
			</control>
			<control halign="left" height="12" name="tbxNotifySelected" readonly="yes" title="Please select export resolution" type="edit" width="160" x="12" y="211" />
			<control halign="left" height="8" name="static9" title="Resize orientation mode" type="static" width="84" x="183" y="16" />
			<control height="10" name="chkDoNotResize" title="Do not resize, only repack" type="check" width="103" x="184" y="29" />
			<control height="10" indeterminate="yes" name="chkOrientationMode" title="Orientation Mode" tristate="yes" type="check" width="100" x="184" y="41" />
			<control halign="left" height="40" name="static5" title="Makes sure better size is\n preserved with aspect ratio\n kept intact (options: Auto,\n Portrait: keep height,\n Landscape: keep width)." type="static" width="100" x="198" y="54" />
			<control halign="left" height="8" name="static6" title="Export comic book to:" type="static" width="79" x="325" y="16" />
			<control height="10" name="radUseSource" title="Source lister" type="radio" width="55" x="331" y="28" />
			<control checked="yes" height="10" name="radUseDestination" title="Destination lister" type="radio" width="74" x="331" y="40" />
			<control halign="left" height="10" name="static4" title="Select custom size" type="static" width="69" x="191" y="103" />
			<control halign="center" height="8" name="static2" title="Wi&amp;dth" type="static" width="26" x="190" y="117" />
			<control enable="no" halign="center" height="12" name="imgRWidth" title="1280" type="edit" width="28" x="222" y="115" />
			<control halign="center" height="8" name="static3" title="Hei&amp;ght" type="static" width="26" x="190" y="130" />
			<control enable="no" halign="center" height="12" name="imgRHeight" title="800" type="edit" width="28" x="222" y="128" />
			<control halign="left" height="8" name="static7" title="Output format" type="static" width="51" x="325" y="66" />
			<control height="40" name="cbxOutputFormat" type="combo" width="51" x="329" y="76">
				<contents>
					<item text="7Z  (.cb7)" />
					<item text="ZIP (.cbz)" />
					<item text="RAR (.cbr)" />
				</contents>
			</control>
			<control halign="left" height="8" name="static9" title="Temporary folder" type="static" width="58" x="184" y="167" />
			<control checked="yes" group="yes" height="10" name="radWindowsTemp" title="Windows TEMP folder" type="radio" width="86" x="190" y="178" />
			<control height="10" name="radCustomTempFolder" type="radio" width="13" x="190" y="190" />
			<control halign="left" height="12" name="tbxCustomTempFolder" readonly="yes" title="Select Your Temp Folder" type="edit" width="213" x="203" y="189" />
			<control enable="no" height="14" name="btnSelectFolder" title="..." type="button" width="16" x="420" y="179" />
			<control height="10" name="chkDeselectAsYouProgress" title="Progressively deselect file after conversion" type="check" width="158" x="190" y="209" />
			<control halign="center" height="12" name="tbxQuality" readonly="yes" title="75" type="edit" width="21" x="399" y="122" />
			<control halign="left" height="8" name="static10" title="Quality %" type="static" width="38" x="325" y="111" />
			<control height="10" name="chkEnforceQuality" title="Change to max" type="check" width="65" x="330" y="123" />
			<control halign="left" height="8" name="static11" title="%" type="static" width="7" x="424" y="124" />
			<control halign="left" height="10" name="static8" title="Custom ratio (%)" type="static" width="56" x="190" y="144" />
			<control enable="no" halign="center" height="12" name="tbxRatio" title="75" type="edit" width="16" x="253" y="142" />
			<control halign="left" height="10" name="static12" title="with quality " type="static" width="42" x="275" y="144" />
			<control enable="no" halign="center" height="12" name="tbxQuality" title="90" type="edit" width="16" x="322" y="143" />
			<control checked="yes" height="10" name="chkBackup" title="Backup Converted File" type="check" width="92" x="190" y="224" />
			<control halign="left" height="10" name="static13" title="Prefix" type="static" width="23" x="214" y="235" />
			<control halign="left" height="10" name="static14" title="Suffix" type="static" width="23" x="312" y="235" />
			<control halign="center" height="12" name="tbxPrefix" type="edit" width="62" x="241" y="234" />
			<control halign="center" height="12" name="tbxSuffix" title="_old" type="edit" width="62" x="341" y="234" />
			<control height="25" name="chkCheckName" type="check" width="15" x="189" y="248" />
			<control halign="left" height="29" name="static16" title="Don&apos;t convert, just rename if extension is incorrect (cbr for Rar File, cbz for Zip, cb7 for 7z)" type="static" width="118" x="208" y="254" />
			<control checked="yes" height="10" name="ChkAutoCompress" title="Compress only if average size is bigger than" type="check" width="163" x="204" y="156" />
			<control halign="left" height="12" name="TbxMaxAvgSize" title="1,2" type="edit" width="32" x="369" y="155" />
			<control halign="left" height="10" name="static17" title="Mo" type="static" width="12" x="406" y="156" />
		</dialog>
	</resource>
</resources>
3 Likes

Nice work. I am however having second thoughts about WinRAR necessity, but, hey - if it works and suits your needs, that's excellent. :slight_smile: I'm also not sure why you need a backup option? What I do is: I keep the source (scanned in 300dpi) and just convert it to the destination. Last option to just rename the extension is nice indeed. :slight_smile:

I am sorry, but I really haven't had a time to make this script even better. Besides, it very well suited my needs even up until now. The main idea of my approach was to reduce the resolution to make the files smaller but still readable at certain tablet. The most of the comics are scanned in 300 dpi, and honestly I see no point in keeping all those dots there, unless you use something of very high resolution.

At first the backup option was because I wasn't confident about my code....
I don't use the "Destination Folder" option: I have a download folder where I use cbx2Cbx then I sort my books. I don't archive comicbook with high DPI, so I needed a way to make cbr smaller.
But as you said, I'm very satisfied of what I've done and I couldn't have done it without your base.

This isn't working at all.

Could you be more explicit ?

Added a short showcase video to the head post on how it looks like in real life. :slight_smile:

Hi, this is nearly perfect for the use case that i'm looking for, i also got a ton of zip files which i would like to repack into cbz. My problem right now is that i know some of these got mangeld and are old .rar.

What i would really like to know is if it would be hard to chage the code to also repack .zip instead of just cbz etc. I'm playing around with the vbs code but to be honest i have no idear what i'm doing here.

Or does somebody know of something that will do what i need?

The easiest thing to do is to select all .zip and change them to .cbz before running the script.

  1. Use flat view if you have them all over the subfolders
  2. Filter for .zip files
  3. Rename - change the extension from .zip to .cbz
  4. Run the script
1 Like

There is a tool call Jpeg Archive, that will recompress a jpeg optimising the compression without reducing the quality. In my experience you can expect a 30% reduction is file size.

The page below can explains how it does this, but the short version is. Jpeg is compressed in blocks using a constant compression rate to each block. This tool (when using the smallfry flag) recompresses each bock separately, increasing the compression rate until it starts to see noise.
The result is the file looks the same but its smaller.

I don't use comics but I found a sample CBZ online that was 11.7MB. When I enabled the smallfry compression the output zip went from 9.39MB (after resize) to 6.84MB (after resize and smallfry).

CBx to CBx 1.5.1 .dcf (35.9 KB)

You will need to download jpeg-recompress.exe from here

Updated UI
image
note this was a quick update to see if this was worth trying. Let me know if you have issues or feedback.

1 Like

I have made some updates to suit my use-case which is perhaps not 100% inline with with the original use-case but I believe it should still add value.

For our personal photo library we group images by event (xmas 2018, persons 3rd bday....). Then zip each set. I wanted to go through all of the photos and recompress them to using jpeg-recompress.exe and overwrite the original archive set. I never resize the image, I only recompress it.

Its still a WIP, back up your original image sets first :).

Changes made.

  • For each temp extracted set move all images to single folder. Instead of finding the child folder with the images.
  • Only overwrite original archive if file count matches.
  • Copy some Metadata from original archive to new archive
  • Add compressed tag so I know what has been completed (also skip tagged sets).
  • Added a overall progress dialog that supports Aborting.
  • Added option to hide dialogs for individual steps, including hiding the re-compress dos window.
  • Allow .zip files to be processed
  • Added some logging with levels
  • Restructured code to have more functions.

CBx to CBx 1.5.2 .dcf (57.2 KB)

Hello all,

Thank you for this wonderful tool. I'm trying to use the button but I'm getting a script error:
Error at line 394, position 2
Variable is undefined: 'sRMode' (0x800a01f4)

Anyone know what this means or how to fix it? I don't know much about scripting.

Thanks,

AR

Try this:

CBx to CBx 1.5.2-fixed.dcf (57.2 KB)

1 Like