Nologic 30 Posted February 7, 2016 Share Posted February 7, 2016 (edited) 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 February 23, 2016 by Nologic 1 Link to comment Share on other sites More sharing options...
Nologic 30 Posted February 7, 2016 Author Share Posted February 7, 2016 (edited) 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 February 23, 2016 by Nologic 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