Jump to content

Resize Images


Nologic

Recommended Posts

Nologic

Why?

I had noticed that my Images for People, had grown to over 22gigs...and thought that was a bit excessive, so I wrote this script & after running it those images came in under 3gigs, and as a result I'm a happy camper now. :)

 

Notes:

The Folders this script is to run against must be on ether a local or network mapped drive, as the script isn't setup to handle UNC paths.

This script doesn't scale up images...only scales down.

 

Requirements:

AutoIt

FFMpeg

 

Instructions:

Install AutoIt and set it to execute scripts when double clicked.

 

Create a folder somewhere...lets call it "Resize Images" just to be unimaginative.

 

Now inside "Resize Images" create a sub folder called "Bin".

 

Now extract the contents of FFMpeg's "Bin" folder into your new "Bin" sub folder.

 

Now going back into "Resize Images" folder Right Click on it's background and select "New\AutoIt v3 Script" from the context menu, and Rename it "Resize Images.au3"

 

Now Right Click "Resize Images.au3" & select "Edit Script" from the context menu.

 

Now paste the following code into:

 

 

#Include <Array.au3>
#include <File.au3>
#Include <String.au3>

;================================================================================
;== User Vars
;================================================================================

$sImage_Name   = 'folder.jpg'
$sImage_Folder = 'C:\Users\MEDIACENTER\AppData\Roaming\Emby-Server\metadata\People\'
$iImage_Width  = 680
$iImage_Height = 1000
$sFFMpegPath   = 'F:\My Projects\Resize Images\BIN\'

;================================================================================
;================================================================================


$aAllFiles = _FileListToArrayRec( $sImage_Folder , $sImage_Name , 1 , 1 , 0 , 2 )
For $ii = 1 To $aAllFiles[0]
	; Create File Macro's
	_FileMacros( $aAllFiles[$ii] )

	; Get Stream Info
	$sRandomString = _RandomString()
	RunWait( @ComSpec & ' /c ffprobe.exe -show_streams "' & $aAllFiles[$ii] & '" >"' & @TempDir & '\' & $sRandomString & '.txt"' , $sFFMpegPath , @SW_HIDE )
	$sBuffer = FileRead( @TempDir & '\' & $sRandomString & '.txt' )
	FileDelete( @TempDir & '\' & $sRandomString & '.txt' )

	; Get Height & Width
	$iImageWidth  = _RegExString( $sBuffer , '(?s)(?i)(?:.+?width=(\S+))?'  )
	$iImageHeight = _RegExString( $sBuffer , '(?s)(?i)(?:.+?height=(\S+))?' )

	; Decide to Process File or Not
	If $iImageWidth > $iImage_Width OR $iImageHeight > $iImage_Height Then
		$sTempFile = @ScriptDir & '\' & _RandomString() & $sFileExt
		RunWait( @ComSpec & ' /c ffmpeg.exe -i "' & $aAllFiles[$ii] & '" -vf "scale=iw*min(1\,if(gt(iw\,ih)\,' & $iImage_Width & '/iw\,(' & $iImage_Height & '*sar)/ih)):(floor((ow/dar)/2))*2" "' & $sTempFile & '"' , $sFFMpegPath , @SW_HIDE ) 
		FileDelete( $aAllFiles[$ii] )
		FileMove( $sTempFile , $aAllFiles[$ii] , 9 )
	EndIf
Next
MsgBox( 0 , 'Finished:' , 'Batch Image Resize Complete.' )




Func _RegExString( $sString , $sRegEx )
	Local $sValue = _ArrayToString( StringRegExp( $sString , $sRegEx , 1 ))
	If StringIsFloat( $sValue ) = 1 OR StringIsInt( $sValue ) = 1 Then
		Return Number( $sValue )
	Else
		If $sValue = 'N/A' OR $sValue = 'N' OR $sValue = 'A' Then
			Return ''
		Else
			Return $sValue
		EndIf
	EndIf
EndFunc

Func _RandomString()
	Local $sString , $aSpace[3]

	For $i = 1 To 15
		$aSpace[0] = Chr( Random( 65 ,  90 , 1 )) ; A-Z
		$aSpace[1] = Chr( Random( 97 , 122 , 1 )) ; a-z
		$aSpace[2] = Chr( Random( 48 ,  57 , 1 )) ; 0-9
		$sString &= $aSpace[Random( 0 , 2 , 1 )]
	Next

	Return $sString
EndFunc

Func _FileMacros( $sInFile )
	Global $sFileDir    = StringLeft     ( $sInFile   , StringInStr( $sInFile   , '\' , 0 , -1 ) )
	Global $sFileExt    = StringTrimLeft ( $sInFile   , StringInStr( $sInFile   , '.' , 0 , -1 ) - 1 )
	Global $sFileName   = StringTrimLeft ( $sInFile   , StringInStr( $sInFile   , '\' , 0 , -1 ) )
	Global $sShortName  = StringLeft     ( $sFileName , StringInStr( $sFileName , '.' , 0 , -1 ) - 1 )
	Global $sParent     = StringTrimLeft ( $sFileDir  , StringInStr( $sFileDir  , '\' , 0 , -2 ) )
	Global $sFolderName = StringTrimRight( StringTrimLeft( $sFileDir , StringInStr( $sFileDir , '\' , 0 , -2 ) ) , 1 )
EndFunc

 

 

 

Now you'll have to edit some User Vars to make use of this script on your system. Now in my example use of People images...older versions of Emby used "folder.jpg" however newer ones are making use of "poster.jpg" so you may need to run it twice with different naming.

 

Next you'll have to give the script the path to the images you wish to resize, then the max Width & Height for the images.

 

Finally the path to FFMpeg...normally I'd have this set automatically to the Bin folder holding the script...but I'm getting a lot of scripts depending on FFMpeg...so I'm allowing you to set the path...so you really only have 1 copy on your system...or at least 1 less do to this script allowing you to set it to a different location.

 

Now save the script & execute it by double clicking it.

 

Now go do something else, this will take a while.

 

The script will notify you when it's done.

Edited by Nologic
  • Like 1
Link to comment
Share on other sites

Nologic

Okay took another wack at this, this time looking to run concurrent image resize...to help speed things along.

 

The recommended setting is equal to the number of physical cores your CPU has...in my case since my Ivy has 4...I set it to 4, to keep the system usable...anything above would likely hose the system.

 

This takes two scripts to make this work, I call this "Resize Images Master.au3" & "Resize Images Slave.au3" both are used the same way as the original.

 

Here is the master script.

 

 

#Include <Array.au3>
#include <File.au3>
#Include <String.au3>

;================================================================================
;== User Vars
;================================================================================

$sImage_Name   = 'folder.jpg'
$sImage_Folder = 'C:\Users\MEDIACENTER\AppData\Roaming\Emby-Server\metadata\People\'
$iImage_Width  = 640
$iImage_Height = 1000
$sFFMpegPath   = 'F:\My Projects\Resize Images\BIN\'
$iConcurrent   = 4

;================================================================================
;================================================================================


$aAllFiles = _FileListToArrayRec( $sImage_Folder , $sImage_Name , 1 , 1 , 0 , 2 )
_ArrayDelete( $aAllFiles , 0 )

AdlibRegister( '_Concurrent' , 250 )

While 1
	Sleep( 100 )
WEnd

Func _Concurrent()
	$aProcesslist = ProcessList( 'ffmpeg.exe' )
	If $aProcesslist[0][0] < $iConcurrent Then
		If UBound( $aAllFiles ) <> 0 Then
			$sCurrentFile = _ArrayPop( $aAllFiles )
			If $sCurrentFile <> '' Then
				Run( @AutoItExe & ' "' & @ScriptDir & '\Resize Images Slave.au3" "' & $sCurrentFile & '" "' & $iImage_Width & '" "' & $iImage_Height & '" "' & $sFFMpegPath & '"' )
			EndIf
		Else
			If ProcessExists( 'ffmpeg.exe' ) = 0 Then
				MsgBox( 0 , 'Finished:' , 'Batch Image Resize Complete.' )
				Exit
			EndIf
		EndIf
	EndIf
EndFunc

 

 

 

Now the Slave

 

 

If $CmdLine[0] = 0 OR $CmdLine[0] < 4 Then Exit

; Create File Macro's
_FileMacros( $CmdLine[1] )

; Get Stream Info
$sRandomString = _RandomString()
RunWait( @ComSpec & ' /c ffprobe.exe -show_streams "' & $CmdLine[1] & '" >"' & @TempDir & '\' & $sRandomString & '.txt"' , $CmdLine[4] , @SW_HIDE )
$sBuffer = FileRead( @TempDir & '\' & $sRandomString & '.txt' )
FileDelete( @TempDir & '\' & $sRandomString & '.txt' )

; Get Height & Width
$iImageWidth  = _RegExString( $sBuffer , '(?s)(?i)(?:.+?width=(\S+))?'  )
$iImageHeight = _RegExString( $sBuffer , '(?s)(?i)(?:.+?height=(\S+))?' )

; Decide to Process File or Not
If $iImageWidth > $CmdLine[2] OR $iImageHeight > $CmdLine[3] Then
	$sTempFile = @ScriptDir & '\' & _RandomString() & $sFileExt
	RunWait( @ComSpec & ' /c ffmpeg.exe -i "' & $CmdLine[1] & '" -vf "scale=iw*min(1\,if(gt(iw\,ih)\,' & $CmdLine[2] & '/iw\,(' & $CmdLine[3] & '*sar)/ih)):(floor((ow/dar)/2))*2" "' & $sTempFile & '"' , $CmdLine[4] , @SW_HIDE ) 
	FileDelete( $CmdLine[1] )
	FileMove( $sTempFile , $CmdLine[1] , 9 )
EndIf



Func _RandomString()
	Local $sString , $aSpace[3]

	For $i = 1 To 15
		$aSpace[0] = Chr( Random( 65 ,  90 , 1 )) ; A-Z
		$aSpace[1] = Chr( Random( 97 , 122 , 1 )) ; a-z
		$aSpace[2] = Chr( Random( 48 ,  57 , 1 )) ; 0-9
		$sString &= $aSpace[Random( 0 , 2 , 1 )]
	Next

	Return $sString
EndFunc

Func _FileMacros( $sInFile )
	Global $sFileDir    = StringLeft     ( $sInFile   , StringInStr( $sInFile   , '\' , 0 , -1 ) )
	Global $sFileExt    = StringTrimLeft ( $sInFile   , StringInStr( $sInFile   , '.' , 0 , -1 ) - 1 )
	Global $sFileName   = StringTrimLeft ( $sInFile   , StringInStr( $sInFile   , '\' , 0 , -1 ) )
	Global $sShortName  = StringLeft     ( $sFileName , StringInStr( $sFileName , '.' , 0 , -1 ) - 1 )
	Global $sParent     = StringTrimLeft ( $sFileDir  , StringInStr( $sFileDir  , '\' , 0 , -2 ) )
	Global $sFolderName = StringTrimRight( StringTrimLeft( $sFileDir , StringInStr( $sFileDir , '\' , 0 , -2 ) ) , 1 )
EndFunc

 

 

Edited by Nologic
Link to comment
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
×
×
  • Create New...