Sign in to follow this  
Followers 0
jaberwacky

Pan-O-Rama 2000

1 post in this topic

#1 ·  Posted (edited)

Greetings,

I used to do quite a bit of photo blogging. I used to put several pictures on my blog that were all resized by hand and they would all link to the same place. Eventually I found out about AutoIt, and so I decided to script this repititious task. This script takes anywhere from two to eight images; shrinks them to the height of the shortest image; appends those into a panorama; and finally the panorama is shrunk to a width of 715 pixels. An image wider than 715 pixels would be rejected by the blog that I used.

Images can either be selected via FileOpenDialog or by dragging and dropping images onto the exe.

The main reason for posting this script is because I completely restructured it using AutoItObject. I structured the script according to my best understanding of Model-View-Controller. Well, maybe you'll find it useful, probably not.

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Res_Fileversion=0.0.0.478
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
#AutoIt3Wrapper_AU3Check_Stop_OnWarning=y
#AutoIt3Wrapper_AU3Check_Parameters=-w 1 -w 2 -w 3 -w 4 -w 6 -d
#AutoIt3Wrapper_Run_After=md "%scriptdir%\Versions\%fileversion%"
#AutoIt3Wrapper_Run_After=copy "%in%" "%scriptdir%\Versions\%fileversion%\%scriptfile%%fileversion%.au3"
#AutoIt3Wrapper_Run_After=copy "%out%" "%scriptdir%\Versions\%fileversion%\%scriptfile%%fileversion%.exe"
#AutoIt3Wrapper_Run_Tidy=y
#Tidy_Parameters=/sf
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****

_Singleton(@ScriptName, 0)

#include "AutoItObject.au3"
#include <Array.au3>
#include <Misc.au3>

_AutoItObject_Startup()

Controller()

_AutoItObject_Shutdown()

Exit

#region Controller
Func Controller()
    Local $this = _AutoItObject_Create()
    _AutoItObject_AddProperty($this, "Model", $ELSCOPE_PRIVATE, Model())
    _AutoItObject_AddMethod($this, "Main", "Controller_Main")
    $this.Main()
    Return $this
EndFunc ;==>Controller

Func Controller_Main($this)
    Return $this.Model.Main()
EndFunc ;==>Controller_Main
#endregion Controller

#region View
Func View()
    Local $this = _AutoItObject_Create()
    _AutoItObject_AddMethod($this, "Message", "View_Message")
    _AutoItObject_AddMethod($this, "OpenDirectory", "View_OpenDir")
    _AutoItObject_AddMethod($this, "INIWrite", "View_INIWrite")
    _AutoItObject_AddMethod($this, "PutToClip", "View_PutToClip")
    _AutoItObject_AddMethod($this, "ToConsole", "View_ToConsole")
    Return $this
EndFunc ;==>View

Func View_INIWrite($this, $data)
    Return IniWrite(@ScriptDir & "\Options and Settings.ini", "Options", "Picture Title", $data)
EndFunc ;==>View_INIWrite

Func View_Message($this, $title, $text, $flag = 0)
    Return MsgBox($flag, $title, $text)
EndFunc ;==>View_Message

Func View_OpenDir($this, $dir)
    Return ShellExecute($dir)
EndFunc ;==>View_OpenDir

Func View_PutToClip($this, $data)
    Return ClipPut($data)
EndFunc ;==>View_PutToClip

Func View_ToConsole($this, $data)
    Return ConsoleWrite($data & @CRLF)
EndFunc ;==>View_ToConsole
#endregion View

#region Model
Func Model()
    Local $this = _AutoItObject_Create()
    _AutoItObject_AddProperty($this, "Announcer", $ELSCOPE_PRIVATE, Announcer())
    _AutoItObject_AddProperty($this, "ImageMagick", $ELSCOPE_PRIVATE, ImageMagick())
    _AutoItObject_AddProperty($this, "ImageList", $ELSCOPE_PRIVATE)
    _AutoItObject_AddProperty($this, "ImageCount", $ELSCOPE_PRIVATE)
    _AutoItObject_AddProperty($this, "Limit", $ELSCOPE_PRIVATE)
    _AutoItObject_AddProperty($this, "StartDirectory", $ELSCOPE_PRIVATE)
    _AutoItObject_AddProperty($this, "ToDirectory", $ELSCOPE_PRIVATE)
    _AutoItObject_AddProperty($this, "PicturesDir", $ELSCOPE_PRIVATE)
    _AutoItObject_AddProperty($this, "ToDirectoryTmp", $ELSCOPE_PRIVATE)
    _AutoItObject_AddProperty($this, "Alignment", $ELSCOPE_PRIVATE)
    _AutoItObject_AddProperty($this, "Destination", $ELSCOPE_PRIVATE)
    _AutoItObject_AddProperty($this, "Title", $ELSCOPE_PRIVATE)
    _AutoItObject_AddProperty($this, "ShortestHeight", $ELSCOPE_PRIVATE)
    _AutoItObject_AddProperty($this, "Width", $ELSCOPE_PRIVATE)
    _AutoItObject_AddProperty($this, "", $ELSCOPE_PRIVATE)
    _AutoItObject_AddProperty($this, "", $ELSCOPE_PRIVATE)
    _AutoItObject_AddMethod($this, "Main", "Model1_Main")
    _AutoItObject_AddMethod($this, "SelectImages", "Model_SelectImages", True)
    _AutoItObject_AddMethod($this, "CreateDirectory", "Model_CreateDirectory", True)
    _AutoItObject_AddMethod($this, "SetLimit", "Model_SetLimit", True)
    _AutoItObject_AddMethod($this, "SetStartDirectory", "Model_SetStartDirectory", True)
    _AutoItObject_AddMethod($this, "SetAlignment", "Model_SetAlignment", True)
    _AutoItObject_AddMethod($this, "IncTitleNum", "Model_IncTitleNum", True)
    _AutoItObject_AddMethod($this, "GetShortestHeight", "Model_GetShortestHeight", True)
    _AutoItObject_AddMethod($this, "SetWidth", "Model_SetWidth", True)
    Return $this
EndFunc ;==>Model

Func Model1_Main($this)
    $this.SetLimit()
    $this.SetStartDirectory()
    $this.SelectImages()

    $this.ImageMagick.StartUp()

    #region GetShortestHeight
    Local $ImageList = $this.ImageList
    Local $heightArray[$this.ImageCount]

    For $i = 0 To $this.ImageCount - 1
        $heightArray[$i] = $this.ImageMagick.Height($ImageList[$i]) ; @ScriptDir & "\image.jpg")
    Next

    $this.ShortestHeight = _ArrayMin($heightArray)
    #endregion GetShortestHeight

    $this.PicturesDir = @ScriptDir & "\Pictures\"
    $this.CreateDirectory($this.PicturesDir)

    $this.IncTitleNum()

    $this.ToDirectory = $this.PicturesDir & $this.Title
    $this.CreateDirectory($this.ToDirectory)

    $this.ToDirectoryTmp = $this.ToDirectory & "\tmp\"
    $this.CreateDirectory($this.ToDirectoryTmp)

    #region resize the images to the height of the shortest image
    For $i = 0 To $this.ImageCount - 1
        $this.ImageMagick.Resize($ImageList[$i], "x" & $this.ShortestHeight, $this.ToDirectoryTmp & $this.ImageMagick.Name($ImageList[$i]))
    Next
    #endregion resize the images to the height of the shortest image

    #region Append the shortened images into a panorama
    $this.SetAlignment()
    Local $panoramaTmp = $this.ToDirectoryTmp & "tmp.jpg"
    $this.ImageMagick.Append($this.ToDirectoryTmp & "*.*", $panoramaTmp, $this.Alignment)
    #endregion Append the shortened images into a panorama

    #region Shrink the panorama to 715w or user defined width
    $this.SetWidth()
    Local $panorama = $this.PicturesDir & $this.Title & ".jpg"
    $this.ImageMagick.Resize($panoramaTmp, $this.Width, $panorama)
    #endregion Shrink the panorama to 715w or user defined width

    Switch FileExists($panorama)
        Case 1 ; woo-hoo
            ; (move|copy) the images
            Local $moveCopy = IniRead(@ScriptDir & "\Options and Settings.ini", "Options", "Move or Copy", 1)

            Switch $moveCopy
                Case 0 ; move the originial pictures into the new dir.
                    For $i = 0 To $this.ImageCount - 1
                        Local $checkErr = FileMove($ImageList[$i], $this.ToDirectory & '\' & $this.ImageMagick.Name($ImageList[$i]), 8 + 1)
                        If $checkErr = 0 Then $this.Announcer.ToConsole("FileMove() failed.")
                    Next
                Case 1 ; copy the originial pictures into the new dir. (default)
                    For $i = 0 To $this.ImageCount - 1
                        $checkErr = FileCopy($ImageList[$i], $this.ToDirectory & '\' & $this.ImageMagick.Name($ImageList[$i]), 8 + 1)
                        If $checkErr = 0 Then $this.Announcer.ToConsole("FileCopy() failed.")
                    Next
            EndSwitch

            FileRecycle($panoramaTmp)

            ; delete the shortened images
            $checkErr = DirRemove($this.ToDirectoryTmp, 1)
            If $checkErr = 0 Then $this.Announcer.ToConsole("There was an error deleting: " & $this.ToDirectoryTmp)

            ; For quick and easy pasting to your image host
            Global $copyPanorama = IniRead(@ScriptDir & "\Options and Settings.ini", "Options", "Copy Panorama", 1)
            If $copyPanorama = 1 Then $this.Announcer.PutToClip($panorama)

            ; opens the final directory for user convenience
            Global $openDir = IniRead(@ScriptDir & "\Options and Settings.ini", "Options", "Open Directory", 1)
            If $openDir = 1 Then $this.Announcer.OpenDirectory($this.PicturesDir)

            ; update 'Options and Settings.ini" to reflect the new panorama image count
            IniWrite(@ScriptDir & "\Options and Settings.ini", "Options", "Picture Title", $this.Title + 1)
            $this.Announcer.INIWrite($this.Title + 1)
        Case 0
            $checkErr = DirRemove($this.ToDirectory)
            If $checkErr = 0 Then $this.Announcer.ToConsole("Error removing $toDirectory: " & $this.ToDirectory)
            Exit (9)
    EndSwitch

    $this.ImageMagick.ShutDown()

    Return $this
EndFunc ;==>Model1_Main

Func Model_CreateDirectory($this, $dir, $rashnot = "-R+N")
    Local $checkErr = DirCreate($dir)

    Switch $checkErr
        Case 0
            Exit (12)
        Case Else
            FileSetAttrib($dir, $rashnot)
    EndSwitch

    Return $this
EndFunc ;==>Model_CreateDirectory

Func Model_IncTitleNum($this)
    $this.Title = IniRead(@ScriptDir & "\Options and Settings.ini", "Options", "Picture Title", $this.ImageCount)

    Select
        Case $this.Title = 0 ; in case user sets 'Picture Title' to 0
            $this.Title = 1

        Case $this.Title <= 9 ; prepend a "0" to the file name if the number is < 10
            $this.Title = "0" & $this.Title

        Case $this.Title <> $this.ImageCount ; this is for a seasoned user that has installed a new version to maintain the picture title integrity
            $this.Title = $this.ImageCount + 1
    EndSelect

    Return $this.Title
EndFunc ;==>Model_IncTitleNum

Func Model_SelectImages($this)
    If $CmdLine[0] Then ; if user drops images onto AutoPlog.exe
        Local $list = $CmdLine

        $this.ImageCount = $list[0]

        _ArrayDelete($list, 0) ; delete ImageCount

        ; check to see if too many or too few images were selected...
        If $this.ImageCount > $this.Limit Then
            $this.Announcer.Message("Alert", "You have selected more than " & $this.Limit & " images. Please try again.")
            Exit (7)
        ElseIf $this.ImageCount < 2 Then
            $this.Announcer.Message("Alert", "You have selected less than two images. You must select at least two images. Please try again.")
            Exit (7)
        EndIf
    Else ; select images with a dialog box
        While 1
            ; open the 'FileOpenDialog' so that the user may select their images...
            Local $fileList = FileOpenDialog("Select from 2 - " & $this.Limit & " images...", $this.StartDirectory, "Images (*.jpg;*.jpeg;*.bmp;*.gif;*.png)", 1 + 2 + 4)

            Switch @error
                Case 1
                    $fileList = "EXIT"
                    ExitLoop
            EndSwitch

            $list = StringSplit($fileList, '|')

            $this.ImageCount = $list[0] - 1
            _ArrayDelete($list, 0)

            Local $directory = $list[0]
            _ArrayDelete($list, 0)

            For $i = 0 To $this.ImageCount - 1
                $list[$i] = $directory & '\' & $list[$i]
            Next

            Local $msg = "default"

            ; check to see if too many or too few images were selected...
            Select
                Case $this.ImageCount > $this.Limit
                    $msg = $this.Announcer.Message("Alert", "You have selected more than " & $this.Limit & " images. Please try again.", 5)
                Case $this.ImageCount < 2
                    $msg = $this.Announcer.Message("Alert", "You have selected less than two images. You must select at least two images. Please try again.", 5)
            EndSelect

            Switch $msg
                Case "default" ; continue as normal
                    ExitLoop
                Case 4 ; retry
                    ContinueLoop
                Case 2 ; cancel
                    ExitLoop
            EndSwitch
        WEnd

        Select
            Case $fileList = "EXIT"; this is a total bummer
                Exit (7)
            Case $msg = 2
                Exit (7)
        EndSelect
    EndIf

    $this.ImageList = $list

    Return $this.ImageList
EndFunc ;==>Model_SelectImages

Func Model_SetAlignment($this)
    $this.Alignment = IniRead(@ScriptDir & "\Options and Settings.ini", "Options", "Alignment", 0)

    Switch $this.Alignment
        Case 0 Or ''
            $this.Alignment = "+append" ; horizontal (default)
        Case 1
            $this.Alignment = "-append" ; vertical
        Case -1
            While 1 ; add a "make default" option
                $this.Alignment = InputBox("Vertical or horizontal alignment?", "Alignment:" & @CRLF & @CRLF & "    Horizontal = 0" & @CRLF & "     Vertical = 1")

                If $this.Alignment = 0 Then
                    $this.Alignment = "+append"
                    ExitLoop
                Else
                    $this.Alignment = "-append"
                    ExitLoop
                EndIf
            WEnd
        Case Else
            $this.Alignment = "+append"
    EndSwitch

    Return $this.Alignment
EndFunc ;==>Model_SetAlignment

Func Model_SetLimit($this)
    $this.Limit = IniRead(@ScriptDir & "\Options and Settings.ini", "Options", "Limit", 8)
    If $this.Limit = '' Then $this.Limit = 8
    Return $this.Limit
EndFunc ;==>Model_SetLimit

Func Model_SetStartDirectory($this)
    ; set the directory in which AutoPlog will begin...
    $this.StartDirectory = IniRead(@ScriptDir & "\Options and Settings.ini", "Options", "Start Directory", @DesktopDir)
    If $this.StartDirectory = "" Then $this.StartDirectory = @DesktopDir
    Return $this.StartDirectory
EndFunc ;==>Model_SetStartDirectory

Func Model_SetWidth($this)
    $this.Width = IniRead(@ScriptDir & "\Options and Settings.ini", "Options", "Width", 715)
    Return $this.Width
EndFunc ;==>Model_SetWidth
#endregion Model

#region ImageMagickObject Class
Func ImageMagick()
    Local $this = _AutoItObject_Create()
    _AutoItObject_AddProperty($this, "IMObj", $ELSCOPE_PRIVATE)
    _AutoItObject_AddMethod($this, "Append", "ImageMagick_Append")
    _AutoItObject_AddMethod($this, "Directory", "ImageMagick_Directory")
    _AutoItObject_AddMethod($this, "Extension", "ImageMagick_Extension")
    _AutoItObject_AddMethod($this, "Height", "ImageMagick_Height")
    _AutoItObject_AddMethod($this, "Name", "ImageMagick_FileName")
    _AutoItObject_AddMethod($this, "Resize", "ImageMagick_Resize")
    _autoitObject_AddMethod($this, "ShutDown", "ImageMagick_ShutDown")
    _AutoItObject_AddMethod($this, "StartUp", "ImageMagick_StartUp")
    _AutoItObject_AddMethod($this, "Width", "ImageMagick_Width")
    Return $this
EndFunc ;==>ImageMagick

Func ImageMagick_Append($this, $from, $to, $horzVert = "+append")
    Return $this.IMObj.Convert($from, $horzVert, $to)
EndFunc ;==>ImageMagick_Append

Func ImageMagick_Directory($this, $image)
    Return $this.IMObj.Identify("-format", "%[directory]", $image)
EndFunc ;==>ImageMagick_Directory

Func ImageMagick_Extension($this, $image)
    Return $this.IMObj.Identify("-format", "%[extension]", $image)
EndFunc ;==>ImageMagick_Extension

Func ImageMagick_FileName($this, $image)
    Return $this.IMObj.Identify("-format", "%f", $image)
EndFunc ;==>ImageMagick_FileName

Func ImageMagick_Height($this, $image)
    Return $this.IMObj.Identify("-format", "%[height]", $image)
EndFunc ;==>ImageMagick_Height

Func ImageMagick_Resize($this, $image, $resize, $to)
    Return $this.IMObj.Convert($this.Directory($image) & '\' & $this.Name($image), "-thumbnail", $resize, $to)
EndFunc ;==>ImageMagick_Resize

Func ImageMagick_ShutDown($this)
    $this.IMObj = 0
    Local $pid = Run(@ComSpec & " /c /s /u RegSvr32""" & @SystemDir & "\ImageMagickObject.dll", '', @SW_HIDE)
    ProcessWaitClose($pid, 300000)
    If $pid = 0 Then $this.Announcer.ToConsole("Run() timed out.")
    If @error <> 0 And @extended = 0xCCCCCCCC Then $this.Announcer.ToConsole("Invalid PID.")
    FileDelete(@SystemDir & "\ImageMagickObject.dll")
    Return $this.IMObj
EndFunc ;==>ImageMagick_ShutDown

Func ImageMagick_StartUp($this)
    Local $checkErr = FileInstall("C:\Program Files (x86)\ImageMagick-6.6.1-Q16\ImageMagickObject.dll", @SystemDir & "\", 1)

    Switch $checkErr
        Case 0 ; "FileInstall() did not install 'ImageMagickObject.dll'"
            Exit (11)
        Case 1
            Local $pid = Run(@ComSpec & " /c /s RegSvr32 " & @SystemDir & "\ImageMagickObject.dll", '', @SW_HIDE)
            ProcessWaitClose($pid, 30000)
            If $pid = 0 Then
                $this.Announcer.ToConsole("Run() timed out.")
                $this.Announcer.Message("Error", "An error occured while copying ImageMagickObject.dll")
                Exit
            EndIf
            If @error <> 0 And @extended = 0xCCCCCCCC Then $this.Announcer.ToConsole("Invalid PID.")
    EndSwitch

    $this.IMObj = ObjCreate("ImageMagickObject.MagickImage.1")

    If Not IsObj($this.IMObj) Then
        $this.Announcer.ToConsole("this.IMObj is not an object")
    EndIf

    Return $this.IMObj
EndFunc ;==>ImageMagick_StartUp
#endregion ImageMagickObject Class

#region Announcer
Func Announcer()
    Local $this = _AutoItObject_Create()
    _AutoItObject_AddProperty($this, "View", $ELSCOPE_PRIVATE, View())
    _AutoItObject_AddMethod($this, "Message", "Announcer_Message")
    _AutoItObject_AddMethod($this, "INIWrite", "Announcer_INIWrite")
    _AutoItObject_AddMethod($this, "ToConsole", "Announcer_ToConsole")
    _AutoItObject_AddMethod($this, "PutToClip", "Announcer_PutToClip")
    _AutoItObject_AddMethod($this, "OpenDirectory", "Announcer_OpenDirectory")
    Return $this
EndFunc ;==>Announcer

Func Announcer_INIWrite($this, $data)
    Return $this.View.INIWrite($data)
EndFunc ;==>Announcer_INIWrite

Func Announcer_Message($this, $title, $text, $flag = 0)
    Return $this.View.Message($title, $text, $flag)
EndFunc ;==>Announcer_Message

Func Announcer_OpenDirectory($this, $dir)
    $this.View.OpenDirectory($dir)
EndFunc ;==>Announcer_OpenDirectory

Func Announcer_PutToClip($this, $data)
    Return $this.View.PutToClip($data)
EndFunc ;==>Announcer_PutToClip

Func Announcer_ToConsole($this, $data)
    Return $this.View.ToConsole($data)
EndFunc ;==>Announcer_ToConsole
#endregion Announcer
Edited by jaberwocky6669

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