wakillon

GifCamEx

9 posts in this topic

#1 ·  Posted (edited)

I love GifCam.

Easy and handy to use for create animated gif from capture.

For the fun, i have tried to do it in AutoIt.

m6ECcIR.gif

GifSicle is only used for compress animated Gif when saving or decompress when loading.

Due to a lack of time, I have not re-created all the features of latest GifCam Version.

Warning : Use latest AutoIt release (v3.3.12.0) and script do not work under XP.

 

source and executable are available in the Download Section

 

Hope you like it ! If not, try the Original !  :D

Edited by wakillon
3 people like this

AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Awesome script

mLipok

EDIT: 

added here:

https://www.autoitscript.com/wiki/AutoIt_Programs#Misc.2FOthers.2FNot_yet_grouped

Edited by mLipok

Signature beginning:   Wondering who uses AutoIT and what it can be used for ?
* GHAPI UDF - modest begining - comunication with GitHub REST API *
ADO.au3 UDF     POP3.au3 UDF     XML.au3 UDF    How to use IE.au3  UDF with  AutoIt v3.3.14.x  for other useful stuff click the following button

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API *

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 - BETA * ADO.au3 UDF SMTP Mailer UDF *

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Best coding practices * 

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * 

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2017-06-04

Share this post


Link to post
Share on other sites

Awesome script

mLipok

 

Thanks !

Script is not as efficient as the original, but the job is done !  ;)


AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Very cool wakillon  :thumbsup:

Cool feature to export to avi. ;)

Some shortcut keys would be great to start / stop recording. Is it possible to disable dithering of the gif frames?

 

When I record at 10 fps then the play speed is too fast -> seems that the delay for each frame, except for the 1st frame, is not set.

 

Maybe you are interessted in this (_GDIPlus_GIFAnim.au3)

;coded by UEZ build 2014-06-10
;requires 3.3.11.5+

#include-once
#include <GDIPlus.au3>
#include <Memory.au3>

;_GDIPlus_BitmapConvertTo8Bit
;_GDIPlus_GIFAnimCreateFile
;_GDIPlus_GIFAnimExtractAllFrames
;_GDIPlus_GIFAnimGetFrameCount
;_GDIPlus_GIFAnimGetFrameDelays
;_GDIPlus_GIFAnimGetFrameDelaysFromBinFile
;_GDIPlus_GIFAnimGetFrameDimensionsCount
;_GDIPlus_GIFAnimGetFrameDimensionsList
;_GDIPlus_GIFAnimSelectActiveFrame
;_GDIPlus_ImageGetPropertyItem
;_GDIPlus_ImageSaveAdd
;_GDIPlus_ImageSaveAddImage

; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_GIFAnimGetFrameDimensionsCount
; Description ...: Gets the number of frame dimensions in this Image object.
; Syntax ........: _GDIPlus_GIFAnimGetFrameDimensionsCount($hImage)
; Parameters ....: $hImage              - A handle to an image / bitmap object
; Return values .: The number of frame dimensions in this Image object.
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; ===============================================================================================================================
Func _GDIPlus_GIFAnimGetFrameDimensionsCount($hImage)
    Local Const $aResult = DllCall($__g_hGDIPDll, "int", "GdipImageGetFrameDimensionsCount", "handle", $hImage, "ulong*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return $aResult[2]
EndFunc   ;==>_GDIPlus_GIFAnimGetFrameDimensionsCount

; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_GIFAnimGetFrameDimensionsList
; Description ...: Gets the identifiers for the frame dimensions of this Image object which fills the GUID struct.
; Syntax ........: _GDIPlus_GIFAnimGetFrameDimensionsList($hImage, $iFramesCount)
; Parameters ....: $hImage              - A handle to an image / bitmap object
;                  $iFramesCount        - An integer value.
; Return values .: tagGUID struct
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; ===============================================================================================================================
Func _GDIPlus_GIFAnimGetFrameDimensionsList($hImage, $iFramesCount)
    Local Const $tGUID = DllStructCreate($tagGUID)
    Local Const $aResult = DllCall($__g_hGDIPDll, "int", "GdipImageGetFrameDimensionsList", "handle", $hImage, "struct*", $tGUID, "uint", $iFramesCount)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return $tGUID
EndFunc   ;==>_GDIPlus_GIFAnimGetFrameDimensionsList

; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_GIFAnimGetFrameCount
; Description ...: Gets the frame count of the loaded gif by passing the GUID struct
; Syntax ........: _GDIPlus_GIFAnimGetFrameCount($hImage, $tGUID)
; Parameters ....: $hImage              - A handle to an image / bitmap object
;                  $tGUID               - A struct to a GUID that specifies the frame dimension.
; Return values .: The amount of frames from a GIF animated image handle
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......: _GDIPlus_ImageLoadFromFile _GDIPlus_BitmapCreateFromFile
; Link ..........:
; ===============================================================================================================================
Func _GDIPlus_GIFAnimGetFrameCount($hImage, $tGUID)
    Local Const $aResult = DllCall($__g_hGDIPDll, "int", "GdipImageGetFrameCount", "handle", $hImage, "struct*", $tGUID, "ptr*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return $aResult[3]
EndFunc   ;==>_GDIPlus_GIFAnimGetFrameCount

; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_GIFAnimSelectActiveFrame
; Description ...: Selects the frame in this Image object specified by passing the GUID struct and current frame.
; Syntax ........: _GDIPlus_GIFAnimSelectActiveFrame($hImage, $tGUID, $iCurrentFrame)
; Parameters ....: $hImage              - A handle to an image / bitmap object
;                  $tGUID               - A struct to a GUID that specifies the frame dimension.
;                  $iCurrentFrame       - An integer value.
; Return values .: True or False on errors
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......: _GDIPlus_ImageLoadFromFile _GDIPlus_BitmapCreateFromFile
; Link ..........:
; ===============================================================================================================================
Func _GDIPlus_GIFAnimSelectActiveFrame($hImage, $tGUID, $iCurrentFrame)
    Local Const $aResult = DllCall($__g_hGDIPDll, "int", "GdipImageSelectActiveFrame", "handle", $hImage, "struct*", $tGUID, "uint", $iCurrentFrame)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return True
EndFunc   ;==>_GDIPlus_GIFAnimSelectActiveFrame

; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_GIFAnimGetFrameDelays
; Description ...: Gets the delay of each frame from an image handle
; Syntax ........: _GDIPlus_GIFAnimGetFrameDelays($hImage, $iAnimFrameCount)
; Parameters ....: $hImage              - A handle to an image / bitmap object
;                  $iAnimFrameCount     - An integer value.
; Return values .: An array with the information about the delay of each frame or the error code
; Author ........: UEZ
; Modified ......:
; Remarks .......: If frame delays cannot be read try _GDIPlus_GIFAnimGetFrameDelaysFromBinFile instead
; Related .......: _GDIPlus_ImageLoadFromFile _GDIPlus_BitmapCreateFromFile _GDIPlus_ImageGetPropertyItem
; Link ..........:
; ===============================================================================================================================
Func _GDIPlus_GIFAnimGetFrameDelays($hImage, $iAnimFrameCount)
    If $iAnimFrameCount < 2 Then Return SetError(1, 0, 0)
    Local Const $GDIP_PROPERTYTAGFRAMEDELAY = 0x5100
    Local $tPropItem = _GDIPlus_ImageGetPropertyItem($hImage, $GDIP_PROPERTYTAGFRAMEDELAY)
    If IsDllStruct($tPropItem) Then
        Local $iType = $tPropItem.type, $iLength, $tVal
        If $iType Then
            $iLength = $tPropItem.length
            Switch $iType
                Case 1
                    $tVal = DllStructCreate("byte delay[" & $iLength & "]", $tPropItem.value)
                Case 3
                    $tVal = DllStructCreate("short delay[" & Ceiling($iLength / 2) & "]", $tPropItem.value)
                Case 4
                    $tVal = DllStructCreate("long delay[" & Ceiling($iLength / 4) & "]", $tPropItem.value)
                Case Else
                    Return SetError(3, 0, 0)
            EndSwitch
            Local $aFrameDelays[Int($iAnimFrameCount)], $i
            For $i = 0 To UBound($aFrameDelays) - 1
                $aFrameDelays[$i] = $tVal.delay(($i + 1)) * 10
;~              ConsoleWrite($i & ": "& $aFrameDelays[$i] & @CRLF)
            Next
        EndIf
        Return $aFrameDelays
    EndIf
    Return SetError(2, 0, 0)
EndFunc   ;==>_GDIPlus_GIFAnimGetFrameDelays

; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_ImageGetPropertyItem
; Description ...: Gets a specified property item (piece of metadata) from this Image object.
; Syntax ........: _GDIPlus_ImageGetPropertyItem($hImage, $iPropID)
; Parameters ....: $hImage              - A handle to an image object.
;                  $iPropID             - An integer that identifies the property item to be retrieved.
; Return values .: $tagGDIPPROPERTYITEM structure or 0 on errors
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......: _GDIPlus_ImageLoadFromFile _GDIPlus_ImageLoadFromStream
; Link ..........: Property Item Descriptions -> http://msdn.microsoft.com/en-us/library/windows/desktop/ms534416(v=vs.85).aspx
; ===============================================================================================================================
Func _GDIPlus_ImageGetPropertyItem($hImage, $iPropID)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetPropertyItemSize", "handle", $hImage, "uint", $iPropID, "ulong*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Local Static $tBuffer ;why static? because otherwise it would crash when running it as x64 exe (workaround)
    $tBuffer = DllStructCreate("byte[" & $aResult[3] & "]")
    $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetPropertyItem", "handle", $hImage, "uint", $iPropID, "ulong", $aResult[3], "struct*", $tBuffer)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(11, $aResult[0], 0)
    Local Const $tagGDIPPROPERTYITEM = "uint id;ulong length;word type;ptr value"
    Local $tPropertyItem = DllStructCreate($tagGDIPPROPERTYITEM, DllStructGetPtr($tBuffer))
    If @error Then Return SetError(20, $aResult[0], 0)
    Return $tPropertyItem
EndFunc   ;==>_GDIPlus_ImageGetPropertyItem

; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_GIFAnimGetFrameDelaysFromBinFile
; Description ...: Gets the delay of each frame from a binary gif file
; Syntax ........: _GDIPlus_GIFAnimGetFrameDelaysFromBinFile($binGIF, $iAnimFrameCount[, $iDelay = 10])
; Parameters ....: $binGIF              - A binary string with the GIF anim.
;                  $iAnimFrameCount     - An integer value.
; Return values .: An array with the information about the delay of each frame or the error code
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; ===============================================================================================================================
Func _GDIPlus_GIFAnimGetFrameDelaysFromBinFile($binGIF, $iAnimFrameCount)
    If Not IsBinary($binGIF) Then Return SetError(1, 0, 0)
    If $iAnimFrameCount < 2 Then Return SetError(2, 0, 0)
    Local $aFrameDelays = StringRegExp($binGIF, "(?i)0021F904[[:xdigit:]]{2}([[:xdigit:]]{4})", 3)
    If @error Then Return SetError(3, 0, 0)
    Local Const $iDelay = 10
    For $i = 0 To UBound($aFrameDelays) - 1
        $aFrameDelays[$i] = $iDelay * Dec(StringRegExpReplace($aFrameDelays[$i], "([[:xdigit:]]{2})([[:xdigit:]]{2})", "$2$1"))
    Next
    If UBound($aFrameDelays) <> $iAnimFrameCount Then ReDim $aFrameDelays[$iAnimFrameCount]
    Return $aFrameDelays
EndFunc   ;==>_GDIPlus_GIFAnimGetFrameDelaysFromBinFile

; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_GIFAnimExtractAllFrames
; Description ...: Extracts all frames from a GIF animation file with the option to resize the frames
; Syntax ........: _GDIPlus_GIFAnimExtractAllFrames($hImage, $sFilename[, $iJPGQual = 85[, $iW = 0[, $iH = 0[, $iResizeQual = 7[,
;                  $bReverse = False]]]]])
; Parameters ....: $hImage              - A handle to an image / bitmap object
;                  $sFilename           - A string value. Folders will be created if not existing.
;                  $iJPGQual            - [optional] An integer value. Default is 85.
;                  $iW                  - [optional] An integer value. Default is 0.
;                  $iH                  - [optional] An integer value. Default is 0.
;                  $iResizeQual         - [optional] An integer value. Default is 2.
;                  $bReverse            - [optional] A binary value. Default is False.
; Return values .: True or False on errors
; Author ........: UEZ
; Modified ......:
; Remarks .......: All frames will be extracted whereas the filename will be <filename>_XX.<ext>. XX is the amount of frames. If
;                  $bReverse is set True then the frames will be saved in reverse order. If $iW and $iH are zero then no resizing will be done.
; Related .......: _GDIPlus_EncodersGetCLSID _GDIPlus_ParamInit _GDIPlus_BitmapCreateFromScan0 _GDIPlus_GraphicsSetInterpolationMode _GDIPlus_ImageSaveToFile
; Link ..........:
; ===============================================================================================================================
Func _GDIPlus_GIFAnimExtractAllFrames($hImage, $sFilename, $iJPGQual = 85, $iW = 0, $iH = 0, $iResizeQual = 2, $bReverse = False)
    If $sFilename = "" Then Return SetError(1, @error, 0)
    Local Const $iAnimDimCount = _GDIPlus_GIFAnimGetFrameDimensionsCount($hImage)
    If @error Then Return SetError(2, @error, 0)
    Local Const $tGUID = _GDIPlus_GIFAnimGetFrameDimensionsList($hImage, $iAnimDimCount)
    If @error Then Return SetError(3, @error, 0)
    Local Const $iAnimFrameCount = _GDIPlus_GIFAnimGetFrameCount($hImage, $tGUID)
    If @error Then Return SetError(4, @error, 0)
    Local $sPath = StringRegExpReplace($sFilename, "(.+)\\.+", "$1")
    If StringLen($sPath) > 2 Then
        If Not FileExists($sPath) Then DirCreate($sPath)
    EndIf
    Local $sPrefixList = "jpg,png,bmp,gif,tif,", $sSuffix = StringRight($sFilename, 3)
    If Not StringInStr($sPrefixList, $sSuffix) Or StringMid($sFilename, StringLen($sFilename) - 3, 1) <> "." Then
        $sSuffix = "png"
        $sFilename &= ".png"
    EndIf
    Switch $sSuffix
        Case "jpg"
            Local $sCLSID = _GDIPlus_EncodersGetCLSID("JPG")
            Local $tParams = _GDIPlus_ParamInit(1)
            Local $tData = DllStructCreate("int Quality")
            Local $pData = DllStructGetPtr($tData)
            Local $pParams = DllStructGetPtr($tParams)
            $tData.Quality = $iJPGQual
            _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
    EndSwitch
    Local $sPrefix = StringTrimRight($sFilename, 4), $hFrame, $iCurrentFrame = 0, $i, $iRet, $hBitmap, $hGfx, $bError = False, $bResize = False
    If ($iW > 0) And ($iH > 0) And ($iW <> _GDIPlus_ImageGetWidth($hImage)) And ($iH <> _GDIPlus_ImageGetHeight($hImage)) Then
        $bResize = True
        $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH)
        $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap)
        _GDIPlus_GraphicsSetInterpolationMode($hGfx, $iResizeQual)
    EndIf
    Local $iFrame
    For $i = 0 To $iAnimFrameCount
        If $bReverse Then
            $iFrame = $iAnimFrameCount - $i
        Else
            $iFrame = $i
        EndIf
        _GDIPlus_GIFAnimSelectActiveFrame($hImage, $tGUID, $i)
        Switch $bResize
            Case False
                $hFrame = $hImage
            Case Else
                _GDIPlus_GraphicsClear($hGfx, 0x00000000)
                _GDIPlus_GraphicsDrawImageRect($hGfx, $hImage, 0, 0, $iW, $iH)
                $hFrame = $hBitmap
        EndSwitch
        Switch $sSuffix
            Case "jpg"
                $iRet = _GDIPlus_ImageSaveToFileEx($hFrame, $sPrefix & "_" & StringFormat("%0" & StringLen(Int($iAnimFrameCount)) & "i." & $sSuffix, $iFrame), $sCLSID, $pParams)
                If Not $iRet Then $bError = True
            Case Else
                $iRet = _GDIPlus_ImageSaveToFile($hFrame, $sPrefix & "_" & StringFormat("%0" & StringLen(Int($iAnimFrameCount)) & "i." & $sSuffix, $iFrame))
                If Not $iRet Then $bError = True
        EndSwitch
    Next
    If $bResize Then
        _GDIPlus_GraphicsDispose($hGfx)
        _GDIPlus_BitmapDispose($hBitmap)
    EndIf
    Return $bError
EndFunc   ;==>_GDIPlus_GIFAnimExtractAllFrames

; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_GIFAnimCreateFile
; Description ...: Creates a GIF animation file
; Syntax ........: _GDIPlus_GIFAnimCreateFile($aImages, $sFilename[, $iDelay = 100])
; Parameters ....: $aImages             - An array of image handles (animation frames).
;                  $sFilename           - The filename of the GIF animation.
;                  $iDelay              - [optional] An integer value. Default is 100 ms per frame.
; Return values .: True or False on errors
; Author ........: UEZ
; Modified ......:
; Remarks .......: Vista or a higher operating system is required to create a GIF animation!
; Related .......: _GDIPlus_EncodersGetCLSID _GDIPlus_ParamInit _GDIPlus_ParamAdd _GDIPlus_ImageSaveToFileEx
; Link ..........:
; ===============================================================================================================================
Func _GDIPlus_GIFAnimCreateFile($aImages, $sFilename, $iDelay = 100)
    Local Const $GDIP_EVTFrameDimensionTime = 21
    Local $sCLSID = _GDIPlus_EncodersGetCLSID("GIF")
    Local $tMultiFrameParam = DllStructCreate("int;")

    DllStructSetData($tMultiFrameParam, 1, $GDIP_EVTMULTIFRAME)
    Local $tParams = _GDIPlus_ParamInit(1)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGSAVEFLAG, 1, $GDIP_EPTLONG, DllStructGetPtr($tMultiFrameParam))

    Local $hStream = _WinAPI_CreateStreamOnHGlobal()
    Local $tGUID = _WinAPI_GUIDFromString($sCLSID)
    _GDIPlus_ImageSaveToStream($aImages[1], $hStream, DllStructGetPtr($tGUID), DllStructGetPtr($tParams))

    DllStructSetData($tMultiFrameParam, 1, $GDIP_EVTFRAMEDIMENSIONTIME)
    $tParams = _GDIPlus_ParamInit(1)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGSAVEFLAG, 1, $GDIP_EPTLONG, DllStructGetPtr($tMultiFrameParam))

    Local $i
    For $i = 2 To $aImages[0] - 1
        _GDIPlus_ImageSaveAddImage($aImages[1], $aImages[$i], $tParams)
    Next

    DllStructSetData($tParams, 1, $GDIP_EVTLASTFRAME)
    $tParams = _GDIPlus_ParamInit(1)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGSAVEFLAG, 1, $GDIP_EPTLONG, DllStructGetPtr($tMultiFrameParam))
    _GDIPlus_ImageSaveAddImage($aImages[1], $aImages[$i], $tParams)

    DllStructSetData($tParams, 1, $GDIP_EVTFLUSH)
    $tParams = _GDIPlus_ParamInit(1)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGSAVEFLAG, 1, $GDIP_EPTLONG, DllStructGetPtr($tMultiFrameParam))
    _GDIPlus_ImageSaveAdd($aImages[$i], $tParams)

    Local $hMemory = _WinAPI_GetHGlobalFromStream($hStream)
    Local $iMemSize = _MemGlobalSize($hMemory)
    Local $pMem = _MemGlobalLock($hMemory)
    Local $tData = DllStructCreate("byte[" & $iMemSize & "]", $pMem)
    Local $bData = DllStructGetData($tData, 1)
    _WinAPI_ReleaseStream($hStream)
    _MemGlobalFree($hMemory)

    $bData = StringRegExpReplace($bData, "(?i)(0021F904[[:xdigit:]]{2})[[:xdigit:]]{4}", "${1}" & StringRegExpReplace(Hex(Int($iDelay / 10), 4), "([[:xdigit:]]{2})([[:xdigit:]]{2})", "$2$1"))
    Local $iExtended  = @extended

    Local $hFile = FileOpen($sFilename, 2)
    If @error Then Return SetError(2, 0, False)
    FileWrite($hFile, Binary($bData))
    FileClose($hFile)

    If Not $iExtended Then Return SetError(1, 0, False)
    Return SetExtended($iExtended, True)
EndFunc

Func _GDIPlus_GIFAnimCreateFileFromImageFiles($aFrames, $sGIFFileName, $bReplay = True)
    Local $tagGIFHeader = "byte Header[6];byte Width[2];byte Height[2];byte PackedField[1];byte BackgroundColorIndex[1];byte PixelAspectRatio[1];"
    Local $tGIFHeader_1frame = DllStructCreate($tagGIFHeader & "byte ColorTable[768];")
    Local $hFile = _WinAPI_CreateFile($aFrames[0][0], 2, 2), $nBytes
    _WinAPI_ReadFile($hFile, DllStructGetPtr($tGIFHeader_1frame), DllStructGetSize($tGIFHeader_1frame), $nBytes)
    _WinAPI_CloseHandle($hFile)
    Local $iColorTableSize = 3 * 2^(BitAND($tGIFHeader_1frame.PackedField, 7) + 1)
    Local $tGIFHeader_File = DllStructCreate($tagGIFHeader & "byte ColorTable[" & $iColorTableSize & "];byte ApplicationBlockExtension[18]")
    $tGIFHeader_File.Header = $tGIFHeader_1frame.Header
    $tGIFHeader_File.Width = $tGIFHeader_1frame.Width
    $tGIFHeader_File.Height = $tGIFHeader_1frame.Height
    $tGIFHeader_File.PackedField = $tGIFHeader_1frame.PackedField
    $tGIFHeader_File.BackgroundColorIndex = $tGIFHeader_1frame.BackgroundColorIndex
    $tGIFHeader_File.PixelAspectRatio = $tGIFHeader_1frame.PixelAspectRatio
    $tGIFHeader_File.ColorTable = BinaryMid($tGIFHeader_1frame.ColorTable, 1, $iColorTableSize)
    $tGIFHeader_File.ApplicationBlockExtension = Binary("0x21FF0B4E45545343415045322E3003010000")
    Local $bGIFHeader, $i, $b, $p, $d
    For $i = 1 To 8
        $bGIFHeader &= StringTrimLeft(DllStructGetData($tGIFHeader_File, $i), 2)
    Next

    For $i = 0 To UBound($aFrames) - 1
        $b = Binary(FileRead($aFrames[$i][0]))
        $p = Floor(StringInStr($b, "0021F904") / 2)
        $d = Hex(Dec($aFrames[$i][1] / 10), 4)
        If Not $p Then ContinueLoop
        $bGIFHeader &= StringMid(StringRegExpReplace(BinaryMid($b, $p, BinaryLen($b) - $p - 1), "(?i)0021F904([[:xdigit:]]{2})([[:xdigit:]]{4})(.*)", "0021F904${1}" & StringRight($d, 2) & StringLeft($d, 2) & "$3"), 3)
    Next

    $hFile = FileOpen($sGIFFileName, 18)
    FileWrite($hFile, Binary("0x" & $bGIFHeader & "3B"))
    FileClose($hFile)
EndFunc

; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_BitmapConvertTo8Bit
; Description ...: Converts a bitmap to a 8-bit image
; Syntax ........: _GDIPlus_BitmapConvertTo8Bit(Byref $hBitmap[, $iColorCount = 253[,$iDitherType = $GDIP_DitherTypeDualSpiral8x8[,
;                  $iPaletteType = $GDIP_PaletteTypeFixedHalftone252,[$bUseTransparentColor = True]]]])
; Parameters ....: $hBitmap              - A handle to an image / bitmap object
;                  $iColorCount          - [optional] An integer value. Default is 253.
;                  $iDitherType          - [optional] An integer value. Default is $GDIP_DitherTypeDualSpiral8x8. -> http://msdn.microsoft.com/en-us/library/ms534106(v=vs.85).aspx
;                  $iPaletteType         - [optional] An integer value. Default is $GDIP_PaletteTypeFixedHalftone252 . -> http://msdn.microsoft.com/en-us/library/ms534159(v=vs.85).aspx
;                  $bUseTransparentColor - [optional]  A binary value. Default is True.
; Return values .: True or False on errors
; Author ........: UEZ
; Modified ......:
; Remarks .......: Vista or a higher operating system is required
; Related .......: _GDIPlus_PaletteInitialize _GDIPlus_BitmapConvertFormat _GDIPlus_ImageLoadFromFile _GDIPlus_BitmapCreateFromScan0
; Link ..........: http://msdn.microsoft.com/en-us/library/windows/desktop/ms534106(v=vs.85).aspx)
; ===============================================================================================================================
Func _GDIPlus_BitmapConvertTo8Bit(ByRef $hBitmap, $iColorCount = 253, $iDitherType = $GDIP_DitherTypeDualSpiral8x8, $iPaletteType = $GDIP_PaletteTypeFixedHalftone252, $bUseTransparentColor = True)
    $iColorCount = ($iColorCount > 2^8) ? 2^8 - 3 : $iColorCount
    Local $tPalette = _GDIPlus_PaletteInitialize($iColorCount, $iPaletteType, 0, $bUseTransparentColor, $hBitmap)
    If @error Then Return SetError(1, @error, 0)
    Local $iRet = _GDIPlus_BitmapConvertFormat($hBitmap, $GDIP_PXF08INDEXED, $iDitherType, $iPaletteType, $tPalette)
    If @error Then Return SetError(2, @error, 0)
    Return $iRet
EndFunc   ;==>_GDIPlus_BitmapConvertTo8Bit

Func _GDIPlus_BitmapConvertToXBit(ByRef $hBitmap, $iColorCount = 16, $iPixelFormat = $GDIP_PXF04INDEXED, $iDitherType = $GDIP_DitherTypeDualSpiral8x8, $iPaletteType = $GDIP_PaletteTypeFixedHalftone252, $bUseTransparentColor = False)
    Switch $iPixelFormat
        Case $GDIP_PXF08INDEXED
            $iColorCount = ($iColorCount > 2^8) ? 2^8 : $iColorCount
        Case $GDIP_PXF04INDEXED
            $iColorCount = ($iColorCount > 2^4) ? 2^4 : $iColorCount
        Case $GDIP_PXF01INDEXED
            $iPaletteType = $GDIP_PaletteTypeFixedBW
            $iColorCount = 2
        Case Else
            $iPixelFormat = $GDIP_PXF04INDEXED
            $iColorCount = 16
            $iDitherType = $GDIP_DitherTypeDualSpiral8x8
            $iPaletteType = $GDIP_PaletteTypeFixedHalftone252
    EndSwitch
    Local $tPalette = _GDIPlus_PaletteInitialize($iColorCount, $iPaletteType, $iColorCount, $bUseTransparentColor, $hBitmap)
    If @error Then Return SetError(1, @error, 0)
    Local $iRet = _GDIPlus_BitmapConvertFormat($hBitmap, $iPixelFormat, $iDitherType, $iPaletteType, $tPalette)
    If @error Then Return SetError(2, @error, 0)
    Return $iRet
EndFunc   ;==>_GDIPlus_BitmapConvertToXBit

; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_ImageSaveAddImage
; Description ...: Adds a frame to a file or stream specified in a previous call to the _GDIP_SaveImageToFile or _GDIP_SaveImageToStream functions.
; Syntax ........: _GDIPlus_ImageSaveAddImage($hImage, $hImageFrame, $tParams)
; Parameters ....: $hImage              - A handle to an image object.
;                  $hImageFrame         - A handle to an image object that holds the frame to be added.
;                  $tParams             - A dll struct to an EncoderParameters structure that holds parameters required by the image encoder
;                                         used by the save-add operation.
; Return values .: True or False on errors
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......: _GDIPlus_ImageSaveAdd _GDIPlus_ParamInit _GDIP_SaveImageToFile _GDIP_SaveImageToStream _GDIPlus_ImageLoadFromFile _GDIPlus_BitmapCreateFromScan0
; ===============================================================================================================================
Func _GDIPlus_ImageSaveAddImage($hImage, $hImageFrame, $tParams)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSaveAddImage", "handle", $hImage, "handle", $hImageFrame, "struct*", $tParams)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_ImageSaveAddImage

; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_ImageSaveAdd
; Description ...: Adds a frame to a file or stream specified in a previous call to the _GDIP_SaveImageToFile or _GDIP_SaveImageToStream functions.
;                  Use this method to save selected frames from a multiple-frame image to another multiple-frame image.
; Syntax ........: _GDIPlus_ImageSaveAdd($hImage, $tParams)
; Parameters ....: $hImage              - A handle to an image object.
;                  $tParams             - A dll struct to a encoder parameter list structure ($tagGDIPENCODERPARAMS).
; Return values .: True or False on errors
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......: _GDIP_SaveImageToFile _GDIP_SaveImageToStream _GDIPlus_ParamInit _GDIPlus_ImageLoadFromFile _GDIPlus_BitmapCreateFromScan0
; ===============================================================================================================================
Func _GDIPlus_ImageSaveAdd($hImage, $tParams)
    Local $aResult
    $aResult = DllCall($__g_hGDIPDll, "int", "GdipSaveAdd", "handle", $hImage, "struct*", $tParams)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_ImageSaveAdd
Example to load a GIF and play it:

#AutoIt3Wrapper_UseX64=n

#include <Array.au3>
#include <WindowsConstants.au3>
#include "_GDIPlus_GIFAnim.au3"

Global $sGIFFile = FileOpenDialog("Please select a GIF animation file", "", "GIF (*.gif)")
If @error Then Exit

_GDIPlus_Startup()
Global $hGIFImage = _GDIPlus_BitmapCreateFromFile($sGIFFile)
Global Const $iW = _GDIPlus_ImageGetWidth($hGIFImage), $iH = _GDIPlus_ImageGetHeight($hGIFImage)
Global Const $hGUI = GUICreate("GIF Anim UDF Example", $iW, $iH)
Global Const $iPic = GUICtrlCreatePic("", 0, 0, $iW, $iH)
GUISetState()

Global  $iCurrentFrame = 0
Global Const $iAnimDimCount = _GDIPlus_GIFAnimGetFrameDimensionsCount($hGIFImage)
Global Const $tGUID = _GDIPlus_GIFAnimGetFrameDimensionsList($hGIFImage, $iAnimDimCount)
Global Const $iAnimFrameCount =  _GDIPlus_GIFAnimGetFrameCount($hGIFImage, $tGUID)
Global Const $aFrameDelays = _GDIPlus_GIFAnimGetFrameDelays($hGIFImage, $iAnimFrameCount)
_ArrayDisplay($aFrameDelays)
AdlibRegister("PlayAnimPreview", 10)

Do
    If GUIGetMsg() = -3 Then ;$GUI_EVENT_CLOSE = -3
        AdlibUnRegister("PlayAnimPreview")
        _GDIPlus_BitmapDispose($hGIFImage)
        _GDIPlus_Shutdown()
        GUIDelete()
        $binGIFAnim = 0
        Exit
    EndIf
Until False

Func PlayAnimPreview()
    AdlibUnRegister("PlayAnimPreview")
    Local $iDelay = $aFrameDelays[$iCurrentFrame]
    Local Static $iTimerCurrentFrame = TimerInit()
    _GDIPlus_GIFAnimSelectActiveFrame($hGIFImage, $tGUID, $iCurrentFrame)
    Local $hBmp = _GDIPlus_BitmapCreateFromScan0($iW, $iH)
    Local $hGfx = _GDIPlus_ImageGetGraphicsContext($hBmp)
    _GDIPlus_GraphicsClear($hGfx, 0xFFFFFFFF)
    _GDIPlus_GraphicsDrawImageRect($hGfx, $hGIFImage, 0, 0, $iW, $iH)
    Local $hBitmap_GDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmp)
    _WinAPI_DeleteObject(GUICtrlSendMsg($iPic, 0x0172 , 0, $hBitmap_GDI)) ;$STM_SETIMAGE = 0x0172, $IMAGE_BITMAP = 0
    _WinAPI_DeleteObject($hBitmap_GDI)
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_BitmapDispose($hBmp)
    If TimerDiff($iTimerCurrentFrame) > $iDelay Then
        $iCurrentFrame += 1
        $iTimerCurrentFrame = TimerInit()
    EndIf
    If $iCurrentFrame > UBound($aFrameDelays) - 1 Then $iCurrentFrame = 0
    AdlibRegister("PlayAnimPreview", 10)
EndFunc   ;==>PlayAnimPreview
In this example you can see the delay for each frame.

 

And finally how to create a GIF (Vista+ os needed!):

;creates a GIF animation file
#AutoIt3Wrapper_UseX64=n
;~ #AutoIt3Wrapper_Version=b
#include <Screencapture.au3>
#include "_GDIPlus_GIFAnim.au3"
If @OSBuild < 6000 Then Exit MsgBox(16, "ERROR", "Vista or a higher operating system is required to create a GIF animation!", 30)

_GDIPlus_Startup()

Global $iFrames = 200, $aImages[$iFrames + 1] = [$iFrames], $sSave = @ScriptDir & "\Test.gif", $i, $hHBitmap, $iW = 299, $iH = 299, $iX, $iY, $a = 1
;~ Global $aImages[361] = [360], $sSave = "C:\Temp\Test.gif", $i
Global $fEnd, $fTimer = TimerInit()
For $i = 1 To $aImages[0]
    $iX = $i * $a
    $a *= 1.0075
    $iY = 0
    $hHBitmap = _ScreenCapture_Capture("", $iX, $iY, $iX + $iW, $iY + $iH) ;L, T, R, B
    $aImages[$i] = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
    _GDIPlus_BitmapConvertTo8Bit($aImages[$i], 255, $GDIP_DitherTypeDualSpiral8x8)
    _WinAPI_DeleteObject($hHBitmap)
Next
ConsoleWrite(_GDIPlus_GIFAnimCreateFile($aImages, $sSave, 5) & ":" & @error & @CRLF) ;40 -> 25 fps (25 * 40 = 1000)
$fEnd = TimerDiff($fTimer)
ConsoleWrite("Animation created in " & $fEnd & " ms (" & Int($aImages[0] / $fEnd * 1000) & " fps)." & @CRLF)

For $i = 1 To $aImages[0]
    _GDIPlus_ImageDispose($aImages[$i])
Next
_GDIPlus_Shutdown()
Edited by 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

#5 ·  Posted (edited)

 

When I record at 10 fps then the play speed is too fast -> seems that the delay for each frame, except for the 1st frame, is not set.

 

 

Each frames have his delay set.

At the end of record all following identicals frames are "grouped" in a un unique frame with a delay set with the value of all those frames delays.

It permit to reduce gif size.

You probably talk about the pre-viewer who for an unknow reason play a bit too fast.

You can modify play speed in _AnimateGifInAnotherThread function at line 490 :

'68' & _SwapEndian ( Int ( $aFrameDelay[$i]*15 ) ) & _         ; push Milliseconds

Be aware that $aFrameDelay values are in hundredth of second ( as needed in a animated gif) and the asm code need milliseconds.

That's why values were multiply per 10 for be correctly adapted.

But may be ASM is really too fast.... :D

 

Edit : Some Animated Gif Editors do not recognize frame delay < 0.1 second.

Edited by wakillon

AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Afaik each frame has a header with several information -> http://en.wikipedia.org/wiki/GIF#Animated_GIF

I don't know how to group frames and thus its frame delay. There are some GIF anims with different delays per frame.

Edited by 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

If you have a doubt, add

Local $aDelays = _AnimatedGifGetFramesDelays ( $sFileName )
_ArrayDisplay ( $aDelays )

before the "return" of the "_Save" function.

It will display all different frame delays for the Animated Gif that you are saving.

For group identical following frames look at the "_ImageGroupIdenticalFrames" Function.

Oh, and i forget to precise that the Gui can be moved while Recording.

May be you only try to record in static mode... :huh:


AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites

I know how the delay values look but I didn't know that grouping is possible by providing only one delay value for all frames.

If you run the Example to load a GIF and play it from post#4 then you will see also the array with the delay values which I used first to check the GIFs created by your program.
 

Btw, I cannot move the recording window outside the main screen. I have 3 monitors at work. ;)


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 know how the delay values look but I didn't know that grouping is possible by providing only one delay value for all frames.

If you run the Example to load a GIF and play it from post#4 then you will see also the array with the delay values which I used first to check the GIFs created by your program.

 

Btw, I cannot move the recording window outside the main screen. I have 3 monitors at work. ;)

 

Not for all frames, just identical following frames.

For example 10 identical following frames with each a delay of 0.1 sec can be displayed as a frame with a delay of 1 second.

The interest to group them is to have less data to save, and so, a gif smaller.

It's also why i do not display frames count, but gif time, cause when record is stopped identical frames are grouped and the frames count can be different.

Take a look at Remove Duplicate Frames part on imagemagick.org where merging consecutive duplicate images is explained.

GifCamEx Gui Position is limited to the screen coordinates, but you can move it inside it.

I use a Timer for avoid to block script when mouse is down on gui.

The Gui Size can be locked or unlocked between 2 consecutive records.

Then script search Max Size of frames for be able to display or save them whatever their Sizes.

The edit part permit you to increase/decrease frame delays or suppress unwanted frames. ( Right click on frame)


AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

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

  • Similar Content

    • Larnil
      By Larnil
      This script generates Barnsleys Fractal Fern using script only.
      ; version 2017-10-03 ; Barnsley Fractal Fern ; by larnil #include <GUIConstants.au3> Dim $x, $y, $xn, $yn, $n, $r, $dc $WinSize = 800 ; window size ;Create graphics windows AutoItSetOption("GUIOnEventMode", 1) $GUI = GUICreate("Barnsley Fractal Fern", $WinSize, $WinSize, -1, -1) $Graphic = GuiCtrlCreateGraphic(0, 0, $WinSize, $WinSize) GUICtrlSetBkColor(-1, 0x000000) GUICtrlSetGraphic(-1,$GUI_GR_COLOR, 0x00ff00) GUISetState(@SW_SHOW) GUISetOnEvent($GUI_EVENT_CLOSE,"Bye") ;Main $start = TimerInit() _Fern(800) ; hight of fern - can be larger than window MsgBox(0,"Time taken:",Round(TimerDiff($start)/1000,3) &" seconds") While 1 Sleep(100) WEnd Func Bye() Exit EndFunc Func _Fern($height) $f = $height/10.6 ; scale factor. Complete fern is within 0 <= y <= 9.9983 (with no scale) $offset_x = $height/2 - $height/40 ; Side adjustment. Fern is within −2.1820 < x < 2.6558 (with no scale) For $n = 1 To $height*200 ; Number of iterations $r = Random(0, 99, 1) Select Case $r < 85 ; 0-84 = 85% of the time $xn = 0.85 * $x + 0.04 * $y $yn = -0.04 * $x + 0.85 * $y + 1.6 Case $r > 84 AND $r < 92 ; 85-91 = 7% of the time $xn = 0.2 * $x - 0.26 * $y $yn = 0.23 * $x + 0.22 * $y + 1.6 Case $r > 91 AND $r < 99 ; 92-98 = 7% of the time $xn = -0.15 * $x + 0.28 * $y $yn = 0.26 * $x + 0.24 * $y + 0.44 Case Else ; 99-99 = 1% of the time $xn = 0 $yn = 0.16 * $y EndSelect $x = $xn $y = $yn GUICtrlSetGraphic($Graphic, $GUI_GR_PIXEL, $offset_x + $x * $f, $height - $y * $f) Next GUICtrlSetGraphic($Graphic, $GUI_GR_REFRESH) EndFunc ;==> Fern  
      Here is another example where I have used GDI (my very first attempt at using GDI by the way). This script can generate much larger Ferns and save them to file (png). I have used this script to generate a 20000 x 20000 pixel @ 600 dpi image. Looks really good printed out in full size.
      #include <GDIPlus.au3> #include <GUIConstantsEx.au3> ; Param Local Const $iPxColor = 0xFF00FF00 ; Pixel color for fractal Alpha/R/G/B Local Const $iBgColor = 0xFFFFFFFF ; Background color for image Alpha/R/G/B Local Const $iSize = 1000 ; Hight of fern in pixels - image will have this hight and width too Local Const $iIter = $iSize*400 ; Number of iterations - $iSize * 200 is a good starting point ; Call function ;$start = TimerInit() _Fern($iSize,$iIter) ;MsgBox(0,"Time taken:",Round(TimerDiff($start)/1000,3) &" seconds") ; Function for generating Barnsley Fractal Fern Func _Fern($Size,$Iter) _GDIPlus_Startup() ; initialize GDI+ Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($Size, $Size) ; create an empty bitmap Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap) ; get the graphics context of the image _GDIPlus_GraphicsClear($hBmpCtxt, $iBgColor) ; Set the background color for empty bitmap ; Here the magic happens $x=0 ; init $y=0 ; init $f = $Size/10.6 ; scale factor. Complete fern is within 0 <= y <= 9.9983 (with no scale) $offset_x = $Size/2 - $Size/40 ; Side adjustment. Fern is within −2.1820 < x < 2.6558 (with no scale) For $n = 1 To $Iter ; Number of iterations $r = Random(0, 99, 1) Select Case $r < 85 ; 0-84 = 85% of the time $xn = 0.85 * $x + 0.04 * $y $yn = -0.04 * $x + 0.85 * $y + 1.6 Case $r > 84 AND $r < 92 ; 85-91 = 7% of the time $xn = 0.2 * $x - 0.26 * $y $yn = 0.23 * $x + 0.22 * $y + 1.6 Case $r > 91 AND $r < 99 ; 92-98 = 7% of the time $xn = -0.15 * $x + 0.28 * $y $yn = 0.26 * $x + 0.24 * $y + 0.44 Case Else ; 99-99 = 1% of the time $xn = 0 $yn = 0.16 * $y EndSelect $x = $xn $y = $yn _GDIPlus_BitmapSetPixel($hBitmap, $offset_x + $x * $f, $Size - $y * $f, $iPxColor) ; Change pixel color for calculated X,Y Next ; ==> End of magic $File = "\Fractal_Fern_"&StringRight(Hex($iPxColor),6)&"-"&StringRight(Hex($iBgColor),6)&"-"&$iSize&".png" _GDIPlus_ImageSaveToFile($hBitmap, @MyDocumentsDir & $File) ;save bitmap to disk ShellExecute(@MyDocumentsDir & $File); Show it to the world in your default image viewer ; Cleanup GDI+ resources _GDIPlus_GraphicsDispose($hBmpCtxt) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() EndFunc ;==> _Fern  
       

    • UEZ
      By UEZ
      Since I disovered FreeBasic I decided to create a DLL to implement much faster image processing functionality to AutoIt.
      Following functions are implemented yet:
      _GDIPlus_BitmapApplyFilter_BWJJNDithering _GDIPlus_BitmapApplyFilter_Cartoon1 _GDIPlus_BitmapApplyFilter_ColorAccent _GDIPlus_BitmapApplyFilter_Convolution_AnotherBlur _GDIPlus_BitmapApplyFilter_Convolution_BoxBlur _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection1 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection2 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection3 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection4 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection5 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection6 _GDIPlus_BitmapApplyFilter_Convolution_Emboss1 _GDIPlus_BitmapApplyFilter_Convolution_Emboss45Degree _GDIPlus_BitmapApplyFilter_Convolution_EmbossTopLeftBottomRight _GDIPlus_BitmapApplyFilter_Convolution_Gaussian3x3 _GDIPlus_BitmapApplyFilter_Convolution_Gaussian5x5_1 _GDIPlus_BitmapApplyFilter_Convolution_Gaussian5x5_2 _GDIPlus_BitmapApplyFilter_Convolution_GaussianBlur _GDIPlus_BitmapApplyFilter_Convolution_IntenseEmboss _GDIPlus_BitmapApplyFilter_Convolution_Kirsch _GDIPlus_BitmapApplyFilter_Convolution_Laplace1 _GDIPlus_BitmapApplyFilter_Convolution_Laplace2 _GDIPlus_BitmapApplyFilter_Convolution_Laplace3 _GDIPlus_BitmapApplyFilter_Convolution_LaplacianOfGaussian _GDIPlus_BitmapApplyFilter_Convolution_ManualMatrix _GDIPlus_BitmapApplyFilter_Convolution_MotionBlur _GDIPlus_BitmapApplyFilter_Convolution_Outline3x3 _GDIPlus_BitmapApplyFilter_Convolution_Prewitt _GDIPlus_BitmapApplyFilter_Convolution_Sharpen1 _GDIPlus_BitmapApplyFilter_Convolution_Sharpen2 _GDIPlus_BitmapApplyFilter_Convolution_Sobel _GDIPlus_BitmapApplyFilter_Convolution_SovelVsPrewitt _GDIPlus_BitmapApplyFilter_Convolution_TriangleBlur _GDIPlus_BitmapApplyFilter_Convolution_Unsharp _GDIPlus_BitmapApplyFilter_Convolution_Unsharp5x5 _GDIPlus_BitmapApplyFilter_Dilatation _GDIPlus_BitmapApplyFilter_DistortionBlur _GDIPlus_BitmapApplyFilter_Edges _GDIPlus_BitmapApplyFilter_Erosion _GDIPlus_BitmapApplyFilter_FishEye _GDIPlus_BitmapApplyFilter_Indexed _GDIPlus_BitmapApplyFilter_Jitter _GDIPlus_BitmapApplyFilter_Kuwahara _GDIPlus_BitmapApplyFilter_Linellism _GDIPlus_BitmapApplyFilter_Median _GDIPlus_BitmapApplyFilter_Median2 _GDIPlus_BitmapApplyFilter_OilPainting _GDIPlus_BitmapApplyFilter_PenSketch _GDIPlus_BitmapApplyFilter_PenSketch2 _GDIPlus_BitmapApplyFilter_Pixelate _GDIPlus_BitmapApplyFilter_Pointillism _GDIPlus_BitmapApplyFilter_RadialBlur _GDIPlus_BitmapApplyFilter_Raster _GDIPlus_BitmapApplyFilter_Swirl _GDIPlus_BitmapApplyFilter_SymmetricNearestNeighbour _GDIPlus_BitmapApplyFilter_TiltShift _GDIPlus_BitmapApplyFilter_TimeWarp _GDIPlus_BitmapApplyFilter_Wave _GDIPlus_BitmapApplyFilter_XRay  
      Since I am absolutely a newbie in FreeBasic, the DLL may contain errors.  Please report any bug.
       
      FreeBasic source code can be found here: https://pastebin.com/Lugp6rCR
       
      To do:
      add function headers with descriptions speed-up FB code -> partly done add more filters -> ongoing  
      Credits to:
      Jakub Szymanowski rdc Dewald Esterhuizen Santhosh G_  Christian Graus www.gutgames.com  
      Have fun.
       
      Download link: 
       
      You can compare the speed with AutoIt version:
      #AutoIt3Wrapper_Version=b #include <Array.au3> #include <GDIPlus.au3> Global $sFile = FileOpenDialog("Select an image", "", "Images (*.jpg;*.png;*.gif;*.bmp)") If @error Then Exit _GDIPlus_Startup() Global Const $STM_SETIMAGE = 0x0172 Global Const $hImage = _GDIPlus_ImageLoadFromFile($sFile) Global Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Global Const $hGUI = GUICreate("GDI+ Image Filters", $iW * 2, $iH) Global $fProg = 0, $iEnd = $iW * $iH - 1 AdlibRegister("Progress", 490) Global $t = TimerInit() Global Const $hGDIBitmap = _GDIPlus_BitmapApplyFilter_Median($hImage, 4) ConsoleWrite(Round(TimerDiff($t) / 1000, 2) & " s / " & Round(TimerDiff($t) / 60000, 2) & " min" & @CRLF) Global Const $iPic = GUICtrlCreatePic("", 0, 0, $iW - 1, $iH - 1) Global Const $iPic_o = GUICtrlCreatePic("", $iW, 0, $iW - 1, $iH - 1) _WinAPI_DeleteObject(GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap)) Global Const $hGDIBitmap2 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) _WinAPI_DeleteObject(GUICtrlSendMsg($iPic_o, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap2)) GUISetState() AdlibUnRegister("Progress") ToolTip("") Do Until GUIGetMsg() = -3 _GDIPlus_ImageDispose($hImage) _WinAPI_DeleteObject($hGDIBitmap) _WinAPI_DeleteObject($hGDIBitmap2) _GDIPlus_Shutdown() Exit Func Progress() ToolTip(Int($fProg / $iEnd * 100) & " % / " & Round(TimerDiff($t) / 60000, 2) & " min", MouseGetPos(0) + 30, MouseGetPos(1) + 30) EndFunc #Region Symmetric Nearest Neighbour Func _GDIPlus_BitmapApplyFilter_SymmetricNearestNeighbour($hImage, $fRadius = 2, $bGDI = True) ;no alpha channel implemented yet Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iRowOffset, $iX, $iY, $c, $k, $sumR, $sumG, $sumB, $iCount, $xx, $yy, $iR, $iG, $iB, $iR1, $iG1, $iB1, $iR2, $iG2, $iB2, $x, $y For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW For $iX = 0 To $iW - 1 $sumR = 0 $sumG = 0 $sumB = 0 $iCount = 0 $c = DllStructGetData($tPixel, 1, $iRowOffset + $iX) $iR = BitShift(BitAND(0x00FF0000, $c), 16) $iG = BitShift(BitAND(0x0000FF00, $c), 8) $iB = BitAND(0x000000FF, $c) For $yy = -$fRadius To $fRadius For $xx = -$fRadius To $fRadius $k = $iX + $xx $x = $k < 0 ? 0 : $k > $iW - 1 ? $iW - 1 : $k $k = $iY + $yy $y = $k < 0 ? 0 : $k > $iH - 1 ? $iH - 1 : $k $c = DllStructGetData($tPixel, 1, $y * $iW + $x) $iR1 = BitShift(BitAND(0x00FF0000, $c), 16) $iG1 = BitShift(BitAND(0x0000FF00, $c), 8) $iB1 = BitAND(0x000000FF, $c) $k = $iX - $xx $x = $k < 0 ? 0 : $k > $iW - 1 ? $iW - 1 : $k $k = ($iY - $yy) $y = $k < 0 ? 0 : $k > $iH - 1 ? $iH - 1 : $k $c = DllStructGetData($tPixel, 1, $y * $iW + $x) $iR2 = BitShift(BitAND(0x00FF0000, $c), 16) $iG2 = BitShift(BitAND(0x0000FF00, $c), 8) $iB2 = BitAND(0x000000FF, $c) If __DeltaE($iR, $iG, $iB, $iR1, $iG1, $iB1) < __DeltaE($iR, $iG, $iB, $iR2, $iG2, $iB2) Then $sumR += $iR1 $sumG += $iG1 $sumB += $iB1 Else $sumR += $iR2 $sumG += $iG2 $sumB += $iB2 EndIf $iCount += 1 Next Next DllStructSetData($tPixel_Dest, 1, 0xFF000000 + Int($sumR / $iCount) * 0x10000 + Int($sumG / $iCount) * 0x100 + Int($sumB / $iCount), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_SNN" & $fRadius & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc Func __DeltaE($iR1, $iG1, $iB1, $iR2, $iG2, $iB2) Return Sqrt(($iR1 - $iR2) * ($iR1 - $iR2) + ($iG1 - $iG2) * ($iG1 - $iG2) + ($iB1 - $iB2) * ($iB1 - $iB2)) EndFunc #EndRegion #Region Jitter Func _GDIPlus_BitmapApplyFilter_Jitter($hImage, $iAmount = 20, $bGDI = True) Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iX, $iY, $iRowOffset, $fNX, $fNY For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW + 1 For $iX = 0 To $iW - 1 $fNX = $iX + Int((Random() - 0.5) * $iAmount) $fNX = $fNX < 1 ? 1 : $fNX > $iW - 1 ? $iW - 1 : $fNX $fNY = ($iY + Int((Random() - 0.5) * $iAmount)) $fNY = $fNY < 1 ? 1 : $fNY > $iH - 1 ? $iH - 1 : $fNY $fNY *= $iW DllStructSetData($tPixel_Dest, 1, DllStructGetData($tPixel, 1, $fNY + $fNX), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_Jitter" & $iAmount & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc #EndRegion #Region Median Func _GDIPlus_BitmapApplyFilter_Median($hImage, $fRadius = 3, $bGDI = True) Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iX, $iY, $iRowOffset For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW + 1 For $iX = 0 To $iW - 1 DllStructSetData($tPixel_Dest, 1, __Median_Value($iX, $iY, $fRadius, $tPixel, $iW, $iH), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_Median" & $fRadius & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc Func __Median_Value($iPosX, $iPosY, $fRadius, $tPixel, $iW, $iH) Local $iX, $iY, $aColors[1000], $iColors = 0, $iSize = $iW * $iH - 1, $iOff, $e For $iX = $iPosX - $fRadius To $iPosX + $fRadius For $iY = $iPosY - $fRadius To $iPosY + $fRadius $iOff = 1 + $iY * $iW + $iX $aColors[$iColors] = DllStructGetData($tPixel, 1, $iOff < 1 ? 1 : $iOff > $iSize ? $iSize : $iOff) $iColors += 1 Next Next ReDim $aColors[$iColors] ;~ _ArraySort($aColors, 0) $e = $iColors - 1 __ArrayQuickSort1D($aColors, 0, $e) Local $iMid = Floor($iColors / 2), $iMedian If BitAND($iColors, 1) Then $iMedian = Int($aColors[$iMid + 1]) Else $iMedian = Int(($aColors[$iMid] + $aColors[$iMid + 1]) / 2) EndIf Return $iMedian EndFunc #EndRegion  
    • wakillon
      By wakillon
      Animated Gif Analyzer
      Display internal infos from animated gifs
      Global and Local Palettes supported
      A value in red indicate that value is false or useless
      Flashing green text ( BK or TR)  indicate background color and transparent color
      Download available in download section

      I created this script because I needed, for an other project, to know in detail the internal characteristics of animated gif
      I had searched a similar soft on internet but I didnt found anything ...
       
    • wakillon
      By wakillon
      Display internal infos from animated gifs
      Global and Local Palettes supported
      A value in red indicate that value is false or useless
    • rootx
      By rootx
      how can I fit the image when the GUI is maximized? I would like to always measure the 50% height and width of the GUI and is always in the bottom right poistion, and does not lose its quality.
      THX
       
      #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <GDIPlus.au3> #include <Array.au3> #include <WinAPI.au3> #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 615, 437, 192, 124,BitOR($GUI_SS_DEFAULT_GUI,$WS_MAXIMIZEBOX,$WS_TABSTOP)) _GDIPlus_Startup() $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir&"\img.jpg") $hGraphics = _GDIPlus_GraphicsCreateFromHWND($Form1) $resimg = _GDIPlus_ImageResize($hImage,200,300) _GDIPlus_GraphicsDrawImage($hGraphics, $resimg, 0, 0) GUIRegisterMsg($WM_PAINT, "MY_WM_PAINT") ;GUIRegisterMsg($WM_SIZE, "WM_SIZE") GUISetState(@SW_SHOW,$Form1) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func MY_WM_PAINT($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam _WinAPI_RedrawWindow($Form1, 0, 0, $RDW_UPDATENOW) _GDIPlus_GraphicsDrawImage($hGraphics, $resimg, 300, 0) _WinAPI_RedrawWindow($Form1, 0, 0, $RDW_VALIDATE) Return $GUI_RUNDEFMSG EndFunc ;==>MY_WM_PAINT ;Func WM_SIZE($hWnd, $iMsg, $iwParam, $ilParam) ; #forceref $hWnd, $iMsg, $iwParam, $ilParam ; Local $xClient, $yClient ; $xClient = BitAND($ilParam, 0x0000FFFF) ; $yClient = BitShift($ilParam, 16) ; _WinAPI_RedrawWindow($Form1, 0, 0, $RDW_UPDATENOW) ; _GDIPlus_GraphicsDrawImage($hGraphics, $resimg, $xClient/2, $yClient/2) ; _WinAPI_RedrawWindow($Form1, 0, 0, $RDW_VALIDATE) ; ConsoleWrite($xClient & " "&$yClient&@CR) ; Return $GUI_RUNDEFMSG ;EndFunc