[FUNC] Tinify API (Compress Images)

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
TheDewd
Posts: 1510
Joined: 19 Dec 2013, 11:16
Location: USA

[FUNC] Tinify API (Compress Images)

08 May 2017, 11:39

Tinify(ImageIn, [ImageOut, ByRef ObjRet])
The Tinify API, designed as a REST service, allows you to compress and optimize WebP, JPEG and PNG images.

The Tinify function, written for AutoHotkey v1, uses the free public API and does not require authentication or have a maximum upload limit quota.


Parameters:

ImageIn
  • The path to a local or external image file.
  • Path must be the URL to an external image file, or the path to a local image file.
ImageOut (Optional)
  • The path to a local directory, with image filename.
  • Directory will be created if it doesn't exist.
  • Existing images with the same filename will be overwritten.
ByRef ObjRet (Optional)
  • The reference name used to call specific data related to the files. See Usage Example #5.


Function:

Code: Select all

Tinify(ImageIn, ImageOut := "", ByRef ObjRet = "") {
	ComObjError(False)

	IsURL := (InStr(ImageIn, "/") ? 1 : 0)
	ImageIn := (!InStr(ImageIn, ":") && !IsURL ? A_ScriptDir "\" ImageIn : ImageIn)
	ImageOut := (!InStr(ImageOut, ":") ? A_ScriptDir "\" ImageOut : ImageOut)

	If (IsURL) {
		BodyIn := "{""source"":{""url"":""" ImageIn """}}"
	} Else {
		If (!FileExist(ImageIn)) {
			return "Invalid input path."
		}

		FileIn := FileOpen(ImageIn, "r")
		BodyIn := ComObjArray(0x11, FileIn.Length)
		DataIn := NumGet(ComObjValue(BodyIn) + 8 + A_PtrSize)
		FileIn.RawRead(DataIn + 0, FileIn.Length)
		FileIn.Close()
	}

	HttpReq := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	HttpReq.SetTimeouts(0, 60000, 30000, 120000)
	HttpReq.Open("POST", "https://tinypng.com/web/shrink")
	HttpReq.SetRequestHeader("Content-Type", (IsURL ? "application/json" : "application/x-www-form-urlencoded"))
	HttpReq.Send(BodyIn)
	HttpReq.WaitForResponse()

	HTMLDoc := ComObjCreate("HTMLFile")
	HTMLDoc.Write("<meta http-equiv=""X-UA-Compatible"" content=""IE=edge"">")
	ObjRet := HTMLDoc.parentWindow.eval("(" HttpReq.ResponseText ")")
	ObjRet.StrJSON := HttpReq.ResponseText
	ObjRet.ImageIn := ImageIn
	ObjRet.ImageOut := ImageOut

	VarSetCapacity(HTMLDoc, 0)
	HTMLDoc := ""

	OutputURL := ObjRet.output.url

	If (ImageOut && OutputURL <> "") {
		SplitPath, ImageOut, OutFileName, OutDir

		If !FileExist(OutDir) {
			FileCreateDir, % OutDir
		}

		HttpReq.Open("GET", OutputURL)
		HttpReq.Send()
		HttpReq.WaitForResponse()
		FileOut := FileOpen(ImageOut, "w")
		BodyOut := HttpReq.ResponseBody
		DataOut := NumGet(ComObjValue(BodyOut) + 8 + A_PtrSize)
		FileOut.RawWrite(DataOut + 0, BodyOut.MaxIndex() + 1)
		FileOut.Close()
	}

	VarSetCapacity(HttpReq, 0)
	HttpReq := ""

	return (OutputURL = "" ? "Error" : OutputURL)
}


Usage Examples:

Compress external image file from URL / Save locally

Code: Select all

Tinify("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png", "CompressedImage.png")

Compress local image file / Save locally

Code: Select all

Tinify("OriginalImage.png", "CompressedImage.png")

Compress local image file / Save locally / Store output URL to variable

Code: Select all

ImageURL := Tinify("OriginalImage.png", "CompressedImage.png")

Compress local image file / Store output URL to variable

Code: Select all

ImageURL := Tinify("OriginalImage.png")

Compress local image file / Save locally / Return compression data

Code: Select all

ImageURL := Tinify("OriginalImage.png", "CompressedImage.png", MyImage)

MsgBox, % "Input Size: " MyImage.input.size
. "`nInput Type: " MyImage.input.type
. "`nOutput Size: " MyImage.output.size
. "`nOutput Type: " MyImage.output.type
. "`nOutput Width: " MyImage.output.width
. "`nOutput Height: " MyImage.output.height
. "`nOutput Ratio: " MyImage.output.ratio
. "`nOutput URL: " MyImage.output.url
. "`nInput Path: " MyImage.ImageIn
. "`nOutput Path: " MyImage.ImageOut
. "`nJSON String: " MyImage.StrJSON

Compress local image file from directory / Save locally

Code: Select all

Loop, Files, C:\Windows\Web\Wallpaper\*.*, FR
{
    If A_LoopFileExt IN PNG,APNG,JPG,JPEG,WEBP
    {
		; // Replace original
		;Tinify(A_LoopFileLongPath, A_LoopFileLongPath)

		; // New file with suffix
		SplitPath, A_LoopFileLongPath,, Dir, Ext, NameNoExt
		MsgBox, % Dir "\" NameNoExt "-tinified." Ext
    }
}




Previous Version


Tinify Websites
https://tinypng.com/
https://tinyjpg.com/

Tinify API Reference
https://tinypng.com/developers/reference
https://tinyjpg.com/developers/reference
Last edited by TheDewd on 08 Sep 2021, 16:21, edited 35 times in total.
burque505
Posts: 1736
Joined: 22 Jan 2017, 19:37

Re: [FUNC] Tinify API (Compress Images)

08 May 2017, 12:04

@TheDewd: Thank you! The Google .png came in at 7kb. Nice.
Off-topic, I really liked your MS-Office themed GUI example, by the way.
User avatar
TheDewd
Posts: 1510
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [FUNC] Tinify API (Compress Images)

20 Jul 2017, 11:29

Updated the POST URL. The previous URL was no longer working.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: [FUNC] Tinify API (Compress Images)

08 Sep 2017, 11:57

The following returns 0 for me

Code: Select all

Tinify("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png", "TinyGoogle.png")
Can this be fixed?
My Scripts and Functions: V1  V2
User avatar
TheDewd
Posts: 1510
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [FUNC] Tinify API (Compress Images)

08 Sep 2017, 12:03

SKAN wrote:Can this be fixed?
They changed the POST URL again. I've modified the script to reflect the current URL. Please try again! ;)

My method of getting the correct POST URL is using the Network Monitor (Ctrl+Shift+E) in Mozilla Firefox while manually uploading an image file to their main website, and then viewing the Request URL.

I also added File.Close() to unlock the file, and a new example to compress & replace all compatible images files in a directory.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: [FUNC] Tinify API (Compress Images)

08 Sep 2017, 14:58

Very nice and useful utility function. :bravo:
Thanks for creating and sharing this.

I ran a loop on a folder with 164 PNG files aggregating 463KB and was able to download reduced files aggregating 303KB.
However, timeout occurs now and then... and downloaded files have this text: {"error":"InputMissing","message":"Input file is empty"}
I deleted them and ran the loop again to get them fresh.

It will be nice if the function can suppress errors.
My Scripts and Functions: V1  V2
User avatar
TheDewd
Posts: 1510
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [FUNC] Tinify API (Compress Images)

08 Sep 2017, 15:15

SKAN wrote: {"error":"InputMissing","message":"Input file is empty"}
I wish I knew how to reproduce the error.

I tested the following, and all files returned with no error. Any ideas?

Code: Select all

Loop, 25 {
    Tinify("pngTest.png", "pngTest" A_Index ".png")
}
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: [FUNC] Tinify API (Compress Images)

08 Sep 2017, 15:35

Please try with 164 PNGs (48x48) I have attached.
Source: Free Icon Pack from http://www.icon-pack.com/

TinyPNG doesn't seem to like when consecutive requests exceed a certain number.
I guess I have to sleep the script now and then when doing large batch conversions.

:)
Attachments
48x48.zip
(484.98 KiB) Downloaded 282 times
My Scripts and Functions: V1  V2
User avatar
TheDewd
Posts: 1510
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [FUNC] Tinify API (Compress Images)

08 Sep 2017, 15:48

SKAN wrote:Please try with 164 PNGs (48x48) I have attached.
All 164 image files compressed with no errors. TinyPNG has a limit of up to 20 images, max 5 MB each. I did not have any issues though. :(

Code: Select all

Loop, Files, C:\48x48\*.*, FR
{
    If A_LoopFileExt IN PNG,JPG
    {
        Tinify(A_LoopFileLongPath, "C:\48x48Compressed\" A_LoopFileName)
    }
}
Last edited by TheDewd on 29 May 2019, 10:50, edited 1 time in total.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: [FUNC] Tinify API (Compress Images)

08 Sep 2017, 16:00

TheDewd wrote:All 164 image files compressed with no errors.
Thanks for testing and confirming.
I guess my ISP sucks. Good download speeds but bad upload performance.
Keep up the good work!

:)
My Scripts and Functions: V1  V2
User avatar
TheDewd
Posts: 1510
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [FUNC] Tinify API (Compress Images)

31 Oct 2017, 09:39

SKAN wrote:I guess my ISP sucks. Good download speeds but bad upload performance.
You could try changing the Timeouts.

For larger images, I was experiencing errors due to timeouts.

Adding the following line before Send() Open() can help:
TinifyObj.SetTimeouts(600000, 600000, 600000, 600000) 600 Second Wait

Also, keep in mind that the maximum filesize is 5MB.

More info: https://autohotkey.com/boards/viewtopic.php?t=9136
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

[V2] [FUNC] Tinify API (Compress Images)

03 Sep 2021, 17:02

For AutoHotkey V2.
Rewrote this for my personal use, posting here as a backup.

Code: Select all

#Requires AutoHotkey v2.0-
#Warn
#SingleInstance

Tinify("https://www.autohotkey.com/boards/download/file.php?avatar=56166_1531774520.png", "TheDewdAvatar.png")
SoundBeep()


Tinify(ImageIn, ImageOut := "") ; for AHK V2.       TheDewd @ autohotkey.com/boards/viewtopic.php?t=31547
{
    Local IsURL, tinyURL, HttpReq, HttpStatus, FileIn, BodyIn, DataIn, FileOut, BodyOut, DataOut

    IsURL := (InStr(ImageIn, "/") ? 1 : 0)

    If (IsURL)
    {
	       BodyIn := '{"source":{"url":"' . ImageIn . '"}}'
    }
    Else
    {
		    FileIn := FileOpen(ImageIn, "r")
		    BodyIn := ComObjArray(0x11, FileIn.Length)
		    DataIn := NumGet(ComObjValue(BodyIn) + 8 + A_PtrSize, "ptr")
		    FileIn.RawRead(DataIn + 0, FileIn.Length)
		    FileIn.Close()
	  }

    HttpReq := ComObject("WinHttp.WinHttpRequest.5.1")
    HttpReq.SetTimeouts(0, 60000, 30000, 120000)
    HttpReq.Open("POST", "https://tinypng.com/web/shrink")
    HttpReq.SetRequestHeader("Content-Type", (IsURL ? "application/json" : "application/x-www-form-urlencoded"))
    HttpReq.Send(BodyIn)
    HttpReq.WaitForResponse()

    HttpStatus := SubStr(HttpReq.Status, 1, 1)
    If ( HttpStatus = "4" || HttpStatus = "5" )
    {
		    Return HttpReq.ResponseText
	  }

	  tinyURL := HttpReq.GetResponseHeader("Location")

    If ( ImageOut )
    {
        HttpReq.Open("GET", tinyURL)
        HttpReq.Send()
        HttpReq.WaitForResponse()
        FileOut := FileOpen(ImageOut, "w")
        BodyOut := HttpReq.ResponseBody
        DataOut := NumGet(ComObjValue(BodyOut) + 8 + A_PtrSize, "ptr")
        FileOut.RawWrite(DataOut + 0, BodyOut.MaxIndex() + 1)
    }

    Return tinyURL
}
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: [FUNC] Tinify API (Compress Images)

04 Sep 2021, 04:11

Hi, @TheDewd

How to do this with curl?

Code: Select all

curl --request POST --data-binary "@IMG_0257.png" -H "Content-Type: application/x-www-form-urlencoded" https://tinypng.com/web/shrink
returns unauthorized access!
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: [FUNC] Tinify API (Compress Images)

04 Sep 2021, 08:03

Okay, user-agent needed.
I'm using below SKAN/TinyPNGviaCurl as user agent.

Code: Select all

curl -A "SKAN/TinyPNGviaCurl" --request POST --data-binary "@IMG_0257.png" -H "Content-Type: application/x-www-form-urlencoded" https://tinypng.com/web/shrink
User avatar
TheDewd
Posts: 1510
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [FUNC] Tinify API (Compress Images)

08 Sep 2021, 16:00

@SKAN,

I just updated this function.

Hope you like the changes!

viewtopic.php?p=147061#p147061
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: [FUNC] Tinify API (Compress Images)

08 Sep 2021, 18:19

Thanks @TheDewd.
I will try this and post feedback soon.
Rachana
Posts: 1
Joined: 04 Aug 2022, 02:18

Re: [FUNC] Tinify API (Compress Images)

04 Aug 2022, 02:29

you can use jpeg compressor for Tinify with higher accuracy by not losing the original quality of the uploaded images.

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 144 guests