GDI+ help: 'Chop and Crop' an image... Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
kunkel321
Posts: 184
Joined: 30 Nov 2015, 21:19
Facebook: https://www.facebook.com/kunkel321
Google: kunkel321

GDI+ help: 'Chop and Crop' an image...

03 May 2017, 15:46

Hi All,
Would anyone be willing to use your GDI+ awesomeness to make a script which can "chop" (parse?) a large image into smaller tiles, then crop a certain number of pixels from around the edge of each tile? A forum search has produced only this: https://autohotkey.com/board/topic/9699 ... nto-tiles/ I did try tic's tutorials, but the GDI+ stuff is really over my head.

Here is a scenario:
Image
The above image is 640x256. I'd like to chop it into 10 columns and 4 rows. Each of the 40 tiles will be 64x64. Then with each tile, crop off 8 pixels all the way around, leaving an image the is 48x48 (the size of the actual image.) These will get used as icons, so I'd like to preserve the transparent properties.

Any takers? Or at least can anyone point me in the right direction for example code? Thanks all.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: GDI+ help: 'Chop and Crop' an image...  Topic is solved

03 May 2017, 20:11

coming shortly ...
[EDIT:] 14 minutes later ...

Code: Select all

q:: ;gdip split image
vPath = %A_Desktop%\28QIFkh.png
SplitPath, vPath, vName, vDir, vExt, vNameNoExt, vDrive
vTileW := 64, vTileH := 64
;vNewW := 64, vNewH := 64
vNewW := 48, vNewH := 48
vDir = %A_Desktop%\z img %A_Now%
FileCreateDir, % vDir

pToken := Gdip_Startup()
pBitmap := Gdip_CreateBitmapFromFile(vPath)
Gdip_GetDimensions(pBitmap, vImgW, vImgH)
vCountW := Floor(vImgW / vTileW)
vCountH := Floor(vImgH / vTileH)

pBitmapNew := Gdip_CreateBitmap(vNewW, vNewH)
G := Gdip_GraphicsFromImage(pBitmapNew)

;vOffsetAdjX := 0, vOffsetAdjY := 0
vOffsetAdjX := 8, vOffsetAdjY := 8
vRow := 0
pBrush := Gdip_BrushCreateSolid(0xFFFFFFFF)
Loop, % vCountH
{
	vRow += 1, vOffsetY := (vRow-1)*vTileH, vCol := 0
	vOffsetY += vOffsetAdjY
	vRow := Format("{:02}", vRow)
	Loop, % vCountW
	{
		;clear the contents of pBitmapNew
		Gdip_FillRectangle(G, pBrush, 0, 0, vNewW, vNewH)
		vCol += 1, vOffsetX := (vCol-1)*vTileW
		vOffsetX += vOffsetAdjX
		vCol := Format("{:02}", vCol)
		;note: Gdip_DrawImage, destination coordinates, then source coordinates
		Gdip_DrawImage(G, pBitmap, 0, 0, vNewW, vNewH, vOffsetX, vOffsetY, vNewW, vNewH)

		;MsgBox, % vOffsetX " " vOffsetY " " vNewW " " vNewH
		vPath = %vDir%\%vNameNoExt%_%vRow%_%vCol%.%vExt%
		if !FileExist(vPath)
			Gdip_SaveBitmapToFile(pBitmapNew, vPath)
		;hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmapNew)
		;SplashImage, HBITMAP:%hBitmap%, B
	}
}

Gdip_DeleteBrush(pBrush)
Gdip_DisposeImage(pBitmap)
Gdip_DeleteGraphics(G)
Gdip_DisposeImage(pBitmapNew)
Gdip_Shutdown(pToken)
Run, % vDir
MsgBox, % "done"
return
I got stuck because Gdip_GraphicsFromImage requires not just x,y destination coordinates, but w,h as well, i.e. you may want to copy part of an image *and* resize it.

Also slightly confusing is that for a row (a left/right thing), its position is based on a y offset/height (an up/down thing).

[EDIT] Also, I needed to find a way to clear the image each time, or it draws non-transparent elements on top of the last one, so I used a pBrush to do that.

If the image isn't transparent, perhaps you can change the pBrush colour or do this for every new image:

Code: Select all

pBitmapNew := Gdip_CreateBitmap(vNewW, vNewH)
G := Gdip_GraphicsFromImage(pBitmapNew)

Gdip_DeleteGraphics(G)
Gdip_DisposeImage(pBitmapNew)
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
Spawnova
Posts: 370
Joined: 08 Jul 2015, 00:12
Contact:

Re: GDI+ help: 'Chop and Crop' an image...

03 May 2017, 21:12

To keep transparency on images you just need to call Gdip_GraphicsClear() after saving the images.

Code: Select all

Gdip_DrawImage(G, pBitmap, 0, 0, vNewW, vNewH, vOffsetX, vOffsetY, vNewW, vNewH)
Gdip_GraphicsClear(G) ;clears the graphics, leaving clean bitmap for next icon
No need to Delete the graphics or dispose of the image until completely finished. =P
Some of my AHK programs: Platformer Game - Langton's Ant - Raycast light/Pixel Water - Creating HD map of any game
Or check out my Youtube for these plus many more projects! :D
kunkel321
Posts: 184
Joined: 30 Nov 2015, 21:19
Facebook: https://www.facebook.com/kunkel321
Google: kunkel321

Re: GDI+ help: 'Chop and Crop' an image...

04 May 2017, 10:21

AWESOME!!! Thank you very much!

Did it really take you only 14 minutes to make that?!

Question: How does Gdip_GraphicsClear() get utilized? I tried putting it here inside the if statement of the inner loop, but it doesn't seem to result in transparent backgrounds...
EDIT2: See below

Code: Select all

#NoEnv
#SingleInstance force
;#################################
;source Jeewsg https://autohotkey.com//boards/viewtopic.php?f=5&t=31363

q:: ;gdip split image
vPath = %A_Desktop%\28QIFkh.png
SplitPath, vPath, vName, vDir, vExt, vNameNoExt, vDrive
vTileW := 64, vTileH := 64
;vNewW := 64, vNewH := 64
vNewW := 48, vNewH := 48
vDir = %A_Desktop%\z img %A_Now%
FileCreateDir, % vDir

pToken := Gdip_Startup()
pBitmap := Gdip_CreateBitmapFromFile(vPath)
Gdip_GetDimensions(pBitmap, vImgW, vImgH)
vCountW := Floor(vImgW / vTileW)
vCountH := Floor(vImgH / vTileH)

pBitmapNew := Gdip_CreateBitmap(vNewW, vNewH)
G := Gdip_GraphicsFromImage(pBitmapNew)

;vOffsetAdjX := 0, vOffsetAdjY := 0
vOffsetAdjX := 8, vOffsetAdjY := 8
vRow := 0
pBrush := Gdip_BrushCreateSolid(0xFFFFFFFF)
Loop, % vCountH
{
	vRow += 1, vOffsetY := (vRow-1)*vTileH, vCol := 0
	vOffsetY += vOffsetAdjY
	vRow := Format("{:02}", vRow)
	Loop, % vCountW
	{
		;clear the contents of pBitmapNew
		Gdip_FillRectangle(G, pBrush, 0, 0, vNewW, vNewH)
		vCol += 1, vOffsetX := (vCol-1)*vTileW
		vOffsetX += vOffsetAdjX
		vCol := Format("{:02}", vCol)
		;note: Gdip_DrawImage, destination coordinates, then source coordinates
		Gdip_DrawImage(G, pBitmap, 0, 0, vNewW, vNewH, vOffsetX, vOffsetY, vNewW, vNewH)

		;MsgBox, % vOffsetX " " vOffsetY " " vNewW " " vNewH
		vPath = %vDir%\%vNameNoExt%_%vRow%_%vCol%.%vExt%
		if !FileExist(vPath)
		{	
			Gdip_SaveBitmapToFile(pBitmapNew, vPath)
			;Spawnova's bit ##############################################
			Gdip_DrawImage(G, pBitmap, 0, 0, vNewW, vNewH, vOffsetX, vOffsetY, vNewW, vNewH)
			Gdip_GraphicsClear(G) ;clears the graphics, leaving clean bitmap for next icon
			;##########################################################
		}
		;hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmapNew)
		;SplashImage, HBITMAP:%hBitmap%, B
	}
}

Gdip_DeleteBrush(pBrush)
Gdip_DisposeImage(pBitmap)
Gdip_DeleteGraphics(G)
Gdip_DisposeImage(pBitmapNew)
Gdip_Shutdown(pToken)
Run, % vDir
MsgBox, % "done"
return
I also tried it right after this line:

Code: Select all

Gdip_DrawImage(G, pBitmap, 0, 0, vNewW, vNewH, vOffsetX, vOffsetY, vNewW, vNewH)
but that broke the script...

Maybe it should be used in conjunction with the code in Jeeswg's second codebox?

EDIT: I realized that the Gdip_DrawImage() function is already there, so I just added Gdip_GraphicsClear() under it. No luck there. Also I tried the single line "Gdip_GraphicsClear()" under Gdip_SaveBitmapToFile(pBitmapNew, vPath). No luck there.

EDIT2: Here we go. The "Gdip_GraphicsClear()" has to go right after the "Gdip_FillRectangle(G, pBrush, 0, 0, vNewW, vNewH)" -Cool! :dance:

EDIT3: This is awesome Jeeswg! I just now noticed that I don't have to "tell" the script how many rows and columns... This is perfect for my workflow. As I draw more icons, the to-be-chopped image grows in size (row by row). As long as my exported grid of images is named the same thing, I can use the same exact script without changing it. -Super cool! :D :D
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: GDI+ help: 'Chop and Crop' an image...

07 May 2017, 11:24

@Spawnova. Many thanks, very useful to know.

@kunkel321. Glad you liked it.

I just tested, and as you said:
replacing this line (coloured background):
Gdip_FillRectangle(G, pBrush, 0, 0, vNewW, vNewH)
with this line (transparent background):
Gdip_GraphicsClear(G)
worked for me.

For the sake of being *transparent*, it took me longer than 14 minutes. I initially posted when I was nearly finished. I can code things pretty quickly, but as ever, I got stuck on one thing (Gdip_GraphicsFromImage and WH coordinates) and I was unsure about one thing (transparency). Apart from that it was quite entertaining to code.

I had done one similar thing previously, involving taking a screenshot, cutting it into tiles and shuffling the tiles for a 'Picasso'/'carousel'/'merry-go-round' effect or a 'conveyor belt'/'filmstrip' effect:

Use Gdip to split a single image into multiple images - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=29101

Btw did you draw those icons, what did you use to draw them? Also, is that the psychology symbol a few times, and, I noticed one was blank ... mysterious.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
kunkel321
Posts: 184
Joined: 30 Nov 2015, 21:19
Facebook: https://www.facebook.com/kunkel321
Google: kunkel321

Re: GDI+ help: 'Chop and Crop' an image...

08 May 2017, 10:14

jeeswg wrote:Also, is that the psychology symbol a few times, and, I noticed one was blank ... mysterious.
How do you feel about that? ..just kidding. Yea, my day job is school psychologist. No special meaning with the blank one. A few of the images in the middle are logos for sch psych test kits. I drew the rest though. My goto vector graphics app for the last decade has been DrawPlus. Sadly, it's abandonware now. http://www.serif.com/drawplus/ I was pretty annoyed because I had *just* upgraded to version X8, then a month later they announced their shiny new product line. Anyway, here's my workspace:
Image

Thanks for the link to the other gdi+ tool you made. I'm surprised that I didn't find that when I did a forum search.

Return to “Ask For Help”

Who is online

Users browsing this forum: boiler, Br4d0z, casperharkin, Frosti, mikeyww, phucnguyenphi123 and 43 guests