Gdip image filesize is too big Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Scr1pter
Posts: 1272
Joined: 06 Aug 2017, 08:21
Location: Germany

Gdip image filesize is too big

10 Dec 2018, 16:39

Hi guys,

I create 1 image with Gdip by merging the Clipboard content and a file.
It works well, but my problem is that
- either the file size is too big (PNG - about 4 MB)
- or the quality is really really bad (JPG)

I also tried changing the jpg quality, but the result is always the same.

As sheet anchor I could use an IrfanView batch which re-saves the png image as png.
However, I' hope it can be solved with Gdip.

The image file left (wallpaper) is a 357 KB jpg file - so it can't be the reason for the huge file size.
When I create a normal png screenshot (1920x1080) using Gdip, the file size is also about 400 KB.
For this reason I believe there's an error in my code which leads to this illogical huge file size.

Code: Select all

xl := ComObjActive("Excel.Application") ; Anbindung an die aktive Excel-Instanz
ws := xl.ActiveSheet ; Anbindung an das aktive Arbeitsblatt
na := xl.ActiveSheet.Name ; Name des aktuellen Arbeitsblattes
pfad := "C:\Users\USER\Documents\Logitech Gaming Software\Profil-Screenshots\" ; Pfad, in dem sich die Bilder befinden
ziel = %pfad%%na%.png ; Datei = pfad + Arbeitsblattname + .png
wallpaper := "C:\Users\USER\Documents\Logitech Gaming Software\Profil-Screenshots\zhintergrund.jpg" ; wallpaper (links) - 1920x1080 - jpg - 347 KB 
ws.range("A1:V44").copy ; Alles in diesem Bereich kopieren (Codes)

pToken := Gdip_Startup() ; Gdip-Instanz starten
pBitmapNew := Gdip_CreateBitmap(4480, 1440) ; Neues Bild mit Abmessungen 4480x1440 erstellen
G := Gdip_GraphicsFromImage(pBitmapNew) ; Bild aus Bilddatei erstellen
Gdip_SetSmoothingMode(G, 4) ; Anti-Aliasing 4
Gdip_SetInterpolationMode(G, 7) ; Interpolierung 7
pBitmapFileLeft := Gdip_CreateBitmapFromFile(wallpaper) ; Bild links = wallpaper
pBitmapFileRight := Gdip_CreateBitmapFromClipboard() ; Bild rechts = Zwischenablage (Excel-Codes)
Gdip_DrawImage(G, pBitmapFileLeft,  0, 0, 1920, 1080, 0, 0, 1920, 1080) ; Positionierung (x, y), Ziel-Auflösung (x, y), Start (x, y), Ende (x, y)
Gdip_DrawImage(G, pBitmapFileRight, 1920, 0, 2560, 1440, 1, 1, 2560, 1440) ; Positionierung (x, y), Ziel-Auflösung (x, y), Start (x, y), Ende (x, y)
Gdip_SaveBitmapToFile(pBitmapNew, ziel) ; Neu erstelltes Bild in definiertes Verzeichnis speichern
Gdip_DisposeImage(pBitmapNew), Gdip_DisposeImage(pBitmapFileLeft), Gdip_DisposeImage(pBitmapFileRight) ; Alles aus dem Speicher entfernen
Gdip_DeleteGraphics(G) ; Rest-Grafiken löschen
Gdip_Shutdown(pToken) ; Gdip-Instanz schließen
Thanks for any help!

Regards
Please use [code][/code] when posting code!
Keyboard: Logitech G PRO - Mouse: Logitech G502 LS - OS: Windows 10 Pro 64 Bit - AHK version: 1.1.33.09
iseahound
Posts: 1444
Joined: 13 Aug 2016, 21:04
Contact:

Re: Gdip image filesize is too big

11 Dec 2018, 00:51

No, a 4 MB image filesize for PNG is normal. Try taking a screenshot of your desktop wallpaper using gdi+, and take another screenshot of this forum page using gdi+.

Code: Select all

a::
pToken := Gdip_Startup()                                                   ; Gdip-Instanz starten
pBitmap := Gdip_BitmapFromScreen()
Gdip_SaveBitmapToFile(pBitmap, "ziel.png")
Gdip_Shutdown(pToken)                                                      ; Gdip-Instanz schließen
return
A PNG of this webpage is 169 kb.
A PNG of my desktop wallpaper and icons is 4516 kb.

Your code is normal!

(Professional tip: Use jpegmini to compress your JPEG images. Save all your JPEG images with maximum quality and throw them into jpeg mini pro. Unfortunately this program costs $99, but I assume you know how to find things like this on a budget.

JPG of this webpage is 645 kb. (After Jpegmini: 343 kb)
JPG of my desktop wallpaper and icons is 1015 kb. (After Jpegmini: 352 kb)
User avatar
Scr1pter
Posts: 1272
Joined: 06 Aug 2017, 08:21
Location: Germany

Re: Gdip image filesize is too big

11 Dec 2018, 17:52

Thanks for the information!

Well, I solved the problem with a simple IrfanView batch at the end of my AHK script.
IrfanView-Batch:

Code: Select all

@echo off
"C:\Program Files\Foto\IrfanView\i_view64.exe" "C:\Users\USER\Documents\Logitech Gaming Software\Profil-Screenshots\*.png" /convert="C:\Users\USER\Documents\Logitech Gaming Software\Profil-Screenshots\*.jpg" /jpgq=100
End of AHK script (basically the end of the script in post 1 of this thread):

Code: Select all

Run, C:\Program Files\Foto\IrfanView\irfan-convertier.bat, , hide ; IrfanView-Batch-Verknüpfung versteckt starten, um die frisch erstellten Screenshots etwas zu komprimieren
Quality and file size of the final screenshots is absolutely acceptable now.

Thanks anway!
(At least I know that it's not possible with Gdip)

Regards
Please use [code][/code] when posting code!
Keyboard: Logitech G PRO - Mouse: Logitech G502 LS - OS: Windows 10 Pro 64 Bit - AHK version: 1.1.33.09
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: Gdip image filesize is too big

11 Dec 2018, 19:28

Scr1pter wrote:
10 Dec 2018, 16:39
Hi guys,

I create 1 image with Gdip by merging the Clipboard content and a file.
It works well, but my problem is that
- either the file size is too big (PNG - about 4 MB)
- or the quality is really really bad (JPG)

I also tried changing the jpg quality, but the result is always the same.

As sheet anchor I could use an IrfanView batch which re-saves the png image as png.
However, I' hope it can be solved with Gdip.

The image file left (wallpaper) is a 357 KB jpg file - so it can't be the reason for the huge file size.
When I create a normal png screenshot (1920x1080) using Gdip, the file size is also about 400 KB.
For this reason I believe there's an error in my code which leads to this illogical huge file size.

Code: Select all

xl := ComObjActive("Excel.Application") ; Anbindung an die aktive Excel-Instanz
ws := xl.ActiveSheet ; Anbindung an das aktive Arbeitsblatt
na := xl.ActiveSheet.Name ; Name des aktuellen Arbeitsblattes
pfad := "C:\Users\USER\Documents\Logitech Gaming Software\Profil-Screenshots\" ; Pfad, in dem sich die Bilder befinden
ziel = %pfad%%na%.png ; Datei = pfad + Arbeitsblattname + .png
wallpaper := "C:\Users\USER\Documents\Logitech Gaming Software\Profil-Screenshots\zhintergrund.jpg" ; wallpaper (links) - 1920x1080 - jpg - 347 KB 
ws.range("A1:V44").copy ; Alles in diesem Bereich kopieren (Codes)

pToken := Gdip_Startup() ; Gdip-Instanz starten
pBitmapNew := Gdip_CreateBitmap(4480, 1440) ; Neues Bild mit Abmessungen 4480x1440 erstellen
G := Gdip_GraphicsFromImage(pBitmapNew) ; Bild aus Bilddatei erstellen
Gdip_SetSmoothingMode(G, 4) ; Anti-Aliasing 4
Gdip_SetInterpolationMode(G, 7) ; Interpolierung 7
pBitmapFileLeft := Gdip_CreateBitmapFromFile(wallpaper) ; Bild links = wallpaper
pBitmapFileRight := Gdip_CreateBitmapFromClipboard() ; Bild rechts = Zwischenablage (Excel-Codes)
Gdip_DrawImage(G, pBitmapFileLeft,  0, 0, 1920, 1080, 0, 0, 1920, 1080) ; Positionierung (x, y), Ziel-Auflösung (x, y), Start (x, y), Ende (x, y)
Gdip_DrawImage(G, pBitmapFileRight, 1920, 0, 2560, 1440, 1, 1, 2560, 1440) ; Positionierung (x, y), Ziel-Auflösung (x, y), Start (x, y), Ende (x, y)
Gdip_SaveBitmapToFile(pBitmapNew, ziel) ; Neu erstelltes Bild in definiertes Verzeichnis speichern
Gdip_DisposeImage(pBitmapNew), Gdip_DisposeImage(pBitmapFileLeft), Gdip_DisposeImage(pBitmapFileRight) ; Alles aus dem Speicher entfernen
Gdip_DeleteGraphics(G) ; Rest-Grafiken löschen
Gdip_Shutdown(pToken) ; Gdip-Instanz schließen
Thanks for any help!

Regards
I have noticed that Gdip does create large PNG files. PNG is a lossless compression so the files are going to be bigger than JPG but there are different compression methods that PNG can use but Gdip does not allow this to be controlled and the default appears to be fastest method with least compression resulting in big files. I can run the PNG through IrfanView and do nothing but resample the files with a compression level 6 (options 0-9) and save them and almost cut the file sizes in half without any loss of information.

As for the use of the Quality setting with JPG through Gdip, I have not had any problems. Just something like
Gdip_SaveBitmapToFile(pBitmapNew, ziel, 50). The 50 can be something between 1 - 100. Works as expected for me.

On a side note: I really, really like IrfanView. I have gotten a lot of great results with the batch feature on large numbers of images.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: Gdip image filesize is too big  Topic is solved

11 Dec 2018, 19:33

Here is code I wrote just a week ago to do something similar.

Code: Select all

; Uncomment if Gdip.ahk is not in your standard library
;#Include, Gdip.ahk

; Start gdi+
If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}
OnExit, CleanUp

F1::
	WidthTotal := 0, HeightMax := 0
	; Specify the files we are going to use
	FileSelectFile, OutputVar, M3
	Loop, Parse, OutputVar, `n
	{
		if (A_Index = 1)
		{
			FilePath := A_LoopField, Files := {}
			continue
		}
		pBitmap := Gdip_CreateBitmapFromFile(FilePath "\" A_LoopField)
		Width := Gdip_GetImageWidth(pBitmap), Height := Gdip_GetImageHeight(pBitmap)
		WidthTotal += Width, HeightMax := (Height>HeightMax ? Height : HeightMax)
		Files.Push({Name:A_LoopField, pBitmap:pBitmap, Width:Width, Height:Height})
	}

	; Create a bitmap (this will be the entire drawing area we have to play with)
	pBitmap := Gdip_CreateBitmap(WidthTotal, HeightMax)

	; Get a pointer to the graphics of the bitmap, for use with drawing functions
	G := Gdip_GraphicsFromImage(pBitmap)

	X := 0, Y := 0
	for index, File in Files
	{
		Gdip_DrawImage(G, File.pBitmap, X, Y, File.Width, File.Height, 0, 0, File.Width, File.Height)
		Gdip_DisposeImage(File.pBitmap)
		X += File.Width
	}

	; Save the bitmap to file "File.png" (extension can be .png,.bmp,.jpg,.tiff,.gif)
	FilePathName := FileNameCounter(FilePath "\Image (1).JPG")
	Gdip_SaveBitmapToFile(pBitmap, FilePathName, 60) ; Quality 60
	Gdip_DisposeImage(pBitmap)
	Gdip_DeleteGraphics(G)
return

#Esc::ExitApp

CleanUp:
	for index, File in Files
		Gdip_DisposeImage(File.pBitmap)
	Gdip_DisposeImage(pBitmap)
	Gdip_DeleteGraphics(G)
	Gdip_Shutdown(pToken)
	ExitApp
Return

FileNameCounter(FilePathName)
{
	while FileExist(FilePathName)
	{
		SplitPath, FilePathName,, OutDir, OutExtension, OutNameNoExt
		if RegExMatch(OutNameNoExt, "(.*?)\((\d+)\)$", M)
			FilePathName := OutDir "\" M1 "(" M2+1 ")." OutExtension
		else
			FilePathName := OutDir "\" OutNameNoExt " (1)." OutExtension
	}
	return FilePathName
}
It lets you pick multiple image files from a file select and then it combines them side by side and saves the results. I was picking just pairs of pictures that were the same size but you could pick 3, 4, etc pictures of different sizes and it should combine them side by side fine.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Gdip image filesize is too big

11 Dec 2018, 22:45

y'all ppl need imagemagick in ur lives
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: Gdip image filesize is too big

12 Dec 2018, 15:08

swagfag wrote:
11 Dec 2018, 22:45
y'all ppl need imagemagick in ur lives
I have heard of ImageMagick but never used. Just downloaded. The command line capabilities are very robust. Looks great to use with AHK or straight from the command line. This is a good addition to my tool box. It adds many capabilities that would be just too hard or impossible to do with Gdip that AHK could hand off to ImageMagick through a Run command line.

IrfanView is great to use as a stand alone program that is more user friendly to use with a GUI to choose all the options to perform on a batch of images. It has a command line too but I have only used the GUI.

I could have used a command line with either ImageMagick or IrfanView to combine images side by side but I needed the ability to fairly quickly pick the images to combine from thumbnails and auto-name so the code I posted did exactly that. I guess I could have used AHK to do the picking and naming and then create the command line to run but I understand Gdip enough to do it all in AHK, plus I like AHK.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
Scr1pter
Posts: 1272
Joined: 06 Aug 2017, 08:21
Location: Germany

Re: Gdip image filesize is too big

12 Dec 2018, 17:30

Solved the issue thanks to FantasticGuru's post!

Instead of

Code: Select all

Gdip_SaveBitmapToFile(pBitmapNew, ziel, 100) ; Neu erstelltes Bild in definiertes Verzeichnis speichern
I wrote

Code: Select all

Gdip_SaveBitmapToFile(pBitmapNew, ziel, Quality=100) ; Neu erstelltes Bild in definiertes Verzeichnis speichern
because this way I saw it in the Gdip.ahk.
I think this is the reason why the end result was so incredibly bad.
Gdip probably interpreted all values as 0.

This means I don't need IrfanView batches or any additional tools.
(Sure I'll remember the tools mentioned here*, perhaps some day I might use one of them.)

Thanks to all guys in this thread anyway!
Always* nice when so many people help!

Edit
Fixed two typos. *

Regards
Please use [code][/code] when posting code!
Keyboard: Logitech G PRO - Mouse: Logitech G502 LS - OS: Windows 10 Pro 64 Bit - AHK version: 1.1.33.09
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Gdip image filesize is too big

12 Dec 2018, 20:46

That change would cause no difference in the quality setting. AHK does not have names parameters like in python.
User avatar
Scr1pter
Posts: 1272
Joined: 06 Aug 2017, 08:21
Location: Germany

Re: Gdip image filesize is too big

13 Dec 2018, 14:06

C'mon man, don't say the P-Word :o

Yes, I just tested it:
Whatever BS I write as parameter, the end result will always be the same as 0

Code: Select all

Gdip_SaveBitmapToFile(pBitmap, datei, blabla) ; Bild aus Zwischenlage in dem angegebenen Verzeichnis erstellen
is the same as:

Code: Select all

Gdip_SaveBitmapToFile(pBitmap, datei, 0) ; Bild aus Zwischenlage in dem angegebenen Verzeichnis erstellen
As said, I wrote it the same way as seen in the gdip.ahk:

Code: Select all

Gdip_SaveBitmapToFile(pBitmap, sOutput, Quality=75)
Regards
Please use [code][/code] when posting code!
Keyboard: Logitech G PRO - Mouse: Logitech G502 LS - OS: Windows 10 Pro 64 Bit - AHK version: 1.1.33.09
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: Gdip image filesize is too big

13 Dec 2018, 17:21

Scr1pter wrote:
13 Dec 2018, 14:06
Yes, I just tested it:
Whatever BS I write as parameter, the end result will always be the same as 0

Code: Select all

Gdip_SaveBitmapToFile(pBitmap, datei, blabla) ; Bild aus Zwischenlage in dem angegebenen Verzeichnis erstellen
is the same as:

Code: Select all

Gdip_SaveBitmapToFile(pBitmap, datei, 0) ; Bild aus Zwischenlage in dem angegebenen Verzeichnis erstellen
As said, I wrote it the same way as seen in the gdip.ahk:

Code: Select all

Gdip_SaveBitmapToFile(pBitmap, sOutput, Quality=75)

AHK does not have named parameters but if you want to put the name just so you know what the parameter is (which you see alot), you can do this:

Code: Select all

Gdip_SaveBitmapToFile(pBitmap, sOutput, Quality:=75)
That one little colon should make it work.

It is important to realize the parameter still needs to be in the proper "slot", the third in this case, to work.

Also named parameters can be implemented within a function with a little bit of parser code to sort them out. I guess this would be pseudo-named parameters but I have used it to good effect for functions that have a bunch of options through a variadic parameter. This is of course only for functions you author.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Gdip image filesize is too big

13 Dec 2018, 21:13

Better off just using an object as a parameter at that point
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: Gdip image filesize is too big

14 Dec 2018, 13:52

kczx3 wrote:
13 Dec 2018, 21:13
Better off just using an object as a parameter at that point
I don't know. I imagine with using an object you would have to create/clear the object and then assign values to the object outside the function call. Something like this:

Code: Select all

Opt := {}, Opt.Two := "Yes"
MyFunc(13, Opt)
Or within like this:

Code: Select all

MyFunc(13, {Two:"Yes"})
That does not seem very intuitive. Plus the whole problem of how to handle default values for options the user did not provide values. You would have to define the defaults and loop through the option parameter similar to parsing a pseudo-named parameter. The whole point of named parameters being that you only provide the ones you need.

Here is an example of pseudo-named parameters from a function I did:

Code: Select all

;	Example:
;	Image_TextBox("Example Text", "Image_Test.PNG", "Image_Save.PNG", "FontSize=48", "Weight=6", "Margin=10", "Style=Bold",  "Align=Right vCenter")
;
Image_TextBox(Text:="", FilePath:="", SavePath:="", Options*)
{
	; Default Options
	FontSize:=24, Font:="Arial",  Style:="Regular", Align:="Center vCenter", Margin:=0, TextColor:="ffffffff", BoxColor:="ff000000", BorderColor:="ffff0000", Weight:="2", Render:=0, Pos:="Bottom Left", Quality:=75, BoxSize:="Auto"
	; Options as Named Parameters
	for key, Option in Options
	{
		Opt := StrSplit(Option, "=")
		var := Opt.1, val := Opt.2
		%var% := val
	}
This allows for a pretty intuitive function call as well as an intuitive way to set defaults within the function. It is an easy way to set any local variable in the function even if you don't define a default.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Gdip image filesize is too big

14 Dec 2018, 21:26

To each their own. I personally don’t like that approach at all.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: vikasgandhi and 337 guests