Sign in to follow this  
Followers 0
tonyrocks

Contact Sheet with AutoIt - Like Photoshop?

11 posts in this topic

Is there a way to create a contact sheet of  pictures from a folder?  For example, i have a folder of 12 pictures.   I would like to place 4 pictures on one page until i reach 12 pictures total.  In this case there would be three separate jpgs.  Is this possible?

Thanks!

 

Share this post


Link to post
Share on other sites



Very easy using ImageMagick, takes as little as....

$img = ObjCreate("ImageMagickObject.MagickImage.1")
$img.Montage(@ScriptDir & "\Temp\*.bmp","montage.bmp")

...that takes all bmp images in scriptdirtemp and makes a montage of it.

You can change size, crop, how many images you want in each row/column and much more.

Read up on it here...

http://www.imagemagick.org/Usage/montage/

1 person likes this

Share this post


Link to post
Share on other sites

whoa! very cool. I plum forgot about ImageMagick.  Thanks!

-Tony

Share this post


Link to post
Share on other sites

So, not to re-open my own post, but I had some questions about mult-page montages.   I can call montage command with no problem, however I have a folder of about 1000 images.  Is there a AutoIt script that can go through and take 6 files, make a montage image called montage1.jpg and then take the next 6 and name it montage 2.jpg and so on?

Thanks!
-Tony

Share this post


Link to post
Share on other sites

How are your files named ? are they named 1.jpg. 2.jpg. 3.jpg. etc. or do they have actual names or weird names like hh34ggdshg33.jpg ?

Maybe look into FileFindFirstFile and FileFindNextFile in the helpfile, stuff them in an array, and make some loop that does it.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Try this (GDI+ version):

;coded by UEZ build 2014-06-13

#cs
    A4 paper size
    72 dpi (web)    =  595 X  842 pixels
    200 dpi (print) = 1654 X 2339 pixels
    300 dpi (print) = 2480 X 3508 pixels
    600 dpi (print) = 4960 X 7016 pixels

    Letter
    72 dpi (web)    =  612 X  792 pixels
    200 dpi (print) = 1700 X 2200 pixels
    300 dpi (print) = 2550 X 3300 pixels
    600 dpi (print) = 5100 X 6600 pixels

#ce
AutoItSetOption("MustDeclareVars", 1)
#include <GDIPlus.au3>
#include <File.au3>

Global $bRec = 1
Global $sFolder = FileSelectFolder("Select a folder with GDI+ supported images", @ScriptDir, 0, "")
If @error Then Exit MsgBox(16, "Error", "No folder has been selected - exiting script!", 30)
Global $t = TimerInit()
Global $aFiles = _FileListToArrayRec($sFolder, "*.jpg;*.png;*.gif;*.bmp", $FLTAR_FILES, $bRec, $FLTAR_SORT, $FLTAR_FULLPATH)
Global $te = TimerDiff($t)
If UBound($aFiles) = 1 Then Exit MsgBox(16, "Error", "No images found in dir " & $sFolder & " - exiting script!", 30)
Global $sDestFolder = FileSelectFolder("Select destination folder where the contact sheets will be saved to", @ScriptDir, 0, "")
If @error Then Exit MsgBox(16, "Error", "No destination folder has been selected - exiting script!", 30)
If Not FileExists($sDestFolder) Then DirCreate($sDestFolder)
If StringRight($sFolder, 1) = "\" Then $sDestFolder = StringTrimRight($sDestFolder, 1)


ConsoleWrite($aFiles[0] & " image files detected in " & Round($te, 2) & " milli seconds. Processing..." & @CRLF)
_GDIPlus_Startup()
Global $iPieces = 8, $iExtended = 0, $iRet
$t = TimerInit()
$iRet = _GDIPlus_BitmapCreateContactSheets($aFiles, $sDestFolder, $iPieces)
$iExtended = @extended
If $iExtended Then ConsoleWrite($iRet & @CRLF)
$te = TimerDiff($t)
ConsoleWrite("Processed " & $aFiles[0] & " image files in " & Round($te / 1000, 2) & " seconds, added " & $aFiles[0] - $iExtended & " images and created " & Ceiling(($aFiles[0] - $iExtended) / $iPieces ^ 2) & " contact sheets!" & @CRLF)
_GDIPlus_Shutdown()

Func _GDIPlus_BitmapCreateContactSheets($aFiles, $sDestFolder, $iPieces = 4, $iWidth = 842, $iHeight = 595)
    If Not IsArray($aFiles) Then Return SetError(1, 0, 0)
    If UBound($aFiles) = 1 Then Return SetError(2, 0, 0)
    Local $iW = Floor($iWidth / $iPieces), $iH = Floor($iHeight / $iPieces), $iPages = Ceiling($aFiles[0] / $iPieces ^ 2), $iX = 0, $iY = 0, $i, $j = 1, $hBmp_tmp, $iErrors = 0, $sErrorFiles
    Local Const $hBitmap_CS = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight)
    Local Const $hGfx_CS = _GDIPlus_ImageGetGraphicsContext($hBitmap_CS)
    For $i = 1 To $iPages
        _GDIPlus_GraphicsClear($hGfx_CS)
        While $iY < $iPieces
            While $iX < $iPieces
                If $j > $aFiles[0] Then ExitLoop 2
                $hBmp_tmp = _GDIPlus_BitmapFitCenteredToSize($aFiles[$j], $iW, $iH)
                If @error Then
                    $iErrors += 1
                    $sErrorFiles &= $aFiles[$j] & ";"
                    $j += 1
                    ContinueLoop 2
                Else
                    _GDIPlus_GraphicsDrawImageRect($hGfx_CS, $hBmp_tmp, $iW * $iX, $iH * $iY, $iW, $iH)
                    _GDIPlus_BitmapDispose($hBmp_tmp)
                    $iX += 1
                EndIf
                $j += 1
            WEnd
            $iX = 0
            $iY += 1
        WEnd
        $iY = 0
        _GDIPlus_ImageSaveToFile($hBitmap_CS, $sDestFolder & "\ContactSheets" & StringFormat("%0" & StringLen($iPages) & "i", $i) & ".png")
        If $j > $aFiles[0] Then ExitLoop
    Next
    _GDIPlus_GraphicsDispose($hGfx_CS)
    _GDIPlus_BitmapDispose($hBitmap_CS)
    If $iErrors Then Return SetError(1, $iErrors, "Skipped files (" & $iErrors & "): " & $sErrorFiles)
    Return 1
EndFunc   ;==>_GDIPlus_BitmapCreateContactSheets

Func _GDIPlus_BitmapFitCenteredToSize($sFile, $iW, $iH, $bDisplayFilename = True, $sFontname = "Verdana", $bFullpath= False, $bUpscale = False)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromFile($sFile)
    If @error Then Return SetError(10, 0, 0)
    Local Const $iWidth = _GDIPlus_ImageGetWidth($hBitmap), $iHeight = _GDIPlus_ImageGetHeight($hBitmap)
    Local $f, $iW_new, $iH_new
    If $iW >= $iH Then
        If $iWidth > $iHeight Then
            $f = $iW / $iWidth
            If Int($iHeight * $f) > $iH Then $f = $iH / $iHeight
        Else
            $f = $iH / $iHeight
            If Int($iWidth * $f) > $iW Then $f = $iW / $iWidth
        EndIf
    Else
        If $iWidth >= $iHeight Then
            $f = $iW / $iWidth
            If Int($iHeight * $f) > $iH Then $f = $iH / $iHeight
        Else
            $f = $iH / $iHeight
            If Int($iWidth * $f) > $iW Then $f = $iW / $iWidth
        EndIf
    EndIf
    $f = (Not $bUpscale And ($iWidth < $iW) And ($iHeight < $iH)) ? 1 : $f
    $iW_new = Int($iWidth * $f)
    $iH_new = Int($iHeight * $f)
    Local Const $hBitmap_new = _GDIPlus_BitmapCreateFromScan0($iW, $iH), $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap_new)
    _GDIPlus_GraphicsSetInterpolationMode($hGfx, 7)
    _GDIPlus_GraphicsDrawImageRect($hGfx, $hBitmap, ($iW - $iW_new) / 2, ($iH - $iH_new) / 2, $iW_new, $iH_new)
    If $bDisplayFilename Then
        Local $iSize = Int(($iW + $iH) / 40)
        $iSize = ($iSize < 8) ? 8 : ($iSize > 12) ? 12 : $iSize
        _GDIPlus_GraphicsSetTextRenderingHint($hGfx, 4)
        _GDIPlus_GraphicsSetSmoothingMode($hGfx, 2)
        Local Const $hFamily = _GDIPlus_FontFamilyCreate($sFontname)
        Local Const $hFormat = _GDIPlus_StringFormatCreate()
        Local Const $tLayout = _GDIPlus_RectFCreate(0, 0, $iW, $iH)
        _GDIPlus_StringFormatSetLineAlign($hFormat, 2)
        Local Const $hPath = _GDIPlus_PathCreate()
        Local $sPath = (Not $bFullpath) ? StringRegExpReplace($sFile, ".+\\(.+)", "$1") : $sFile
        _GDIPlus_PathAddString($hPath, $sPath, $tLayout, $hFamily, 0, $iSize, $hFormat)
        Local Const $hPen = _GDIPlus_PenCreate(0xFF000000, 1 + Int($iSize / 11))
        Local Const $hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
        _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen)
        _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush)
        _GDIPlus_PathDispose($hPath)
        _GDIPlus_PenDispose($hPen)
        _GDIPlus_BrushDispose($hBrush)
        _GDIPlus_FontFamilyDispose($hFamily)
        _GDIPlus_StringFormatDispose($hFormat)
    EndIf
    _GDIPlus_GraphicsDispose($hGfx)
    Return $hBitmap_new
EndFunc   ;==>_GDIPlus_BitmapFitCenteredToSize

Benchmark: Processed 997 image files in 69.28 seconds, added 993 images and created 16 contact sheets!

Please report any bugs!

Br,

UEZ

Edit1: fixed memory leak

Edit2: fixed a bug in _GDIPlus_BitmapFitCenteredToSize function (calculation) and added text (filename)

Edited by UEZ
1 person likes this

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

Very nice looking!  When running it though I get an error on line 24:

Error: Variable used without being declared.

Share this post


Link to post
Share on other sites

Which AutoIt version are you using?

Br,

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

I am using 3.3.10.2.  looks like i'm a little behind?

Share this post


Link to post
Share on other sites

ok, I upgraded my AutoIt and I no longer get the error.  However after I select the source folder and then the destination folder, nothing seems to happen.  The interface dismisses with no message saying that files are being processed.  

Share this post


Link to post
Share on other sites

Oh wait, found the problem. Apparently there is a problem with using WIndows Server 2008, I have to put this at the top:

_GDIPlus_Startup("gdiplus.dll")

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

  • Similar Content

    • Mechaflash
      By Mechaflash
      Easily capture, edit, and save images from your desktop.

      When working on multiple projects and building documentation, taking screenshots, editing them, and then inserting them into files eats up some time. This little program helps to reduce some of that time by auto-opening your screen capture in the editor of your choice while having the ability to auto-save the captures in a sequenced file naming pattern.

      See the for some detailed information.
    • Mechaflash
      By Mechaflash
      Updated: 7/30/12


      OLD CONTENT BELOW





      Intro:
      When working on multiple projects and building documentation, taking screenshots, editing them, and then inserting them into files eats up some time. This little program helps to reduce some of that time by auto-opening your screen capture in the editor of your choice while having the ability to auto-save the captures in a sequenced file naming pattern.


      Installation:
      Run the Screen Edit vx.x.exe installer.


      You are given a few different options for installation including setting up the shortcuts and the auto-start on login.After the installation is complete, you can either have it start right away, or manually start it via the program menu or shortcuts if applicable.


      Comes packed with an uninstaller.


      Instructions:
      Use your 'Print Screen' button to capture anything on your desktop. If a specific window has focus (you're actively using it), it will capture that window. If no window has focus, it will capture all of your desktops. To do this, just left-click in some empty space on your desktop and it will remove focus from all windows. This also works on multi-monitor setups.


      Alternatively, you can use 'ALT + Print Screen' to capture your entire default desktop (from your Default monitor).Upon performing either action, your captured image will automatically open in your editor (by default, this will be Microsoft Paint).If you have the save feature enabled in the configuration, a numbered file will be created. Every subsequent capture will create a new file in sequential order. You can also change the naming scheme of the files in the configuration as well. This is great when you're working on documentation for multiple projects and need a sequence of screenshots.


      To access the configuration, click on the tray icon for Screen Edit.exe and click 'Edit Configuration File'.


      The configuration settings include:
      Changing the default capture file location
      Auto-Save screen captures
      Changing the file name scheme
      Changing your default editor/viewer
      Changing the JPEG quality of the captured image
      Testing the output of the captured image with the current configuration
      Changing the Auto-Launch options
      To exit the application, click on the tray menu for Screen Edit.exe and click 'Exit'.

      Changes in version 1.1







      Download Links:




    • AGlassman
      By AGlassman
      GreenShot (http://getgreenshot.org/) is a nice, free for personal use, screen capture utility. It is designed to be running all the time (in the system notification tray) and triggered with a Global Hotkey (Print Scrn).

      I prefer to only run it when I need it and have it exit when I'm done, so I wrote this simple script. It starts the utility (if it's not already running), triggers a capture operation, waits for me to finish editing/saving the image, and then closes the utility.

      The only tricky part was determining when it was ready to accept a HotKey to start the capture. My solution was to monitor it's IO count.

      The only downside is that it leaves the tray icon visable until the next tray refresh, because I killed it instead of closing it down normally. (Known problem).

      - Alan G -

      GreenShot_Auto_X86_V1.0.zip


      ; ===================================================================== ; Start GreenShot ; Send it a PrintScreen keyboard commnad ; Wait for a capture ; Shut it down ; ===================================================================== Global $ProcessName = "Greenshot.exe" ; Process Name Global $WindowTitle = "Greenshot image editor" ; Image Editor Window Title Global $RunCmd = "C:\Program Files (x86)\Greenshot\Greenshot.exe" ; Program run Command Global $WorkingDir = "" ; Working Directory ; If GreenShot is not already running If NOT ProcessExists( $ProcessName ) Then ; Execute GreenShot If NOT ShellExecute( $RunCmd, "", $WorkingDir ) Then MsgBox( 16, @ScriptFullPath & " - Error", _ "Program failed to execute. $RunCmd = '" & $RunCmd & "'." ) Exit( 1 ) Else ; Wait for the GreenShot process to exist If NOT ProcessWait( $ProcessName, 5 ) Then MsgBox( 16, @ScriptFullPath & " - Error", _ "Process did not start. $ProcessName = '" & $ProcessName & "'." ) Exit( 1 ) Else ; Wait for a minimum number of IO (So we know it's ready) Global $Ready = False For $i = 1 To 20 Global $IOStats = ProcessGetStats( $ProcessName, 1 ) If $IOStats[1] > 4 Then $Ready = True ExitLoop EndIf Sleep( 250 ) Next ; $i If NOT $Ready Then MsgBox( 16, @ScriptFullPath & " - Error", _ "Process IO Reads not > 700. $ProcessName = '" & $ProcessName & "', $IOStats[1] = '" & $IOStats[1] & "'." ) Exit( 1 ) EndIf EndIf ; NOT ProcessWait EndIf ; NOT ShellExecute EndIf ; NOT ProcessExists ; Send GreenShot a PrintScreen Keyboard command to ; initiate a Capture Send( "{PRINTSCREEN}" ) ; Wait for the Greenshot Image Editor Window to Open ; after I take a shot If NOT WinWaitActive( $WindowTitle, "", 300 ) Then MsgBox( 16, @ScriptFullPath & " - Error", _ "Image Editor Window did not open. $WindowTitle = '" & $WindowTitle & "'." ) Exit( 1 ) EndIf ; Wait for the Greenshot Image Editor Window to Close ; then kill the process WinWaitClose( $WindowTitle ) ProcessClose( $ProcessName ) If NOT ProcessWaitClose( $ProcessName, 5 ) Then MsgBox( 16, @ScriptFullPath & " - Error", _ "Process failed to close. $ProcessName = '" & $ProcessName & "'." ) Exit( 1 ) EndIf ; All done Exit( 0 )