1

Тема: AHK: Gdip - вырезание

Написал код для вырезания круга из картинки, в примере надо прописать путь к картинке и она должна отобразится.
Как правильно вырезать например эллипс, или какие то другие фигуры неправильной формы.
То есть вырезать не их самих, это сделать просто с помощью заливки, а вырезать то что вокруг них.

В примере фигура рисуется с помощью толстой кисти, которая и затирает всё вокруг, какие есть альтернативы такому подходу?



#SingleInstance, Force
#NoEnv

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


File =  

  ;	стороны квадрата в которые будет размещено исходное изображение. Height нужно для тестов с элипсами
 
 
Width := 800
Height := 800

Gui, New, -Caption -DPIScale +E0x80000 +hwndhGui 
Gui, Show, NA
hbm := CreateDIBSection(Width, Height)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)

Gdip_SetInterpolationMode(G, 7)
Gdip_SetSmoothingMode(G, 2)

; 1::
	pBitmap := Gdip_CreateBitmapFromFile(File)
	Gdip_GetImageDimensions(pBitmap, PicW, PicH)
	  ;	нужен прозрачный битмап для копирования в него исходного
	pBitmap2 := Gdip_CreateBitmap(Width, Height) 
	pGraphics := Gdip_GraphicsFromImage(pBitmap2) 

	Gdip_SetInterpolationMode(pGraphics, 7) 
	Gdip_SetSmoothingMode(pGraphics, 0)
	  ;	растягивание картинки в прозрачном битмапе
	Gdip_DrawImage(pGraphics, pBitmap, 0, 0, Width, Height, 0, 0, PicW, PicH)
	Gdip_DisposeImage(pBitmap)
	 ;	из гипотенузы / 2 вычитаем радиус. Это вычисление не работает с элипсами
	r := Sqrt(Height**2 + Width**2) - (Width > Height ? Width : Height)  
	r := Ceil(r / 2), r2 := r / 2
	  ;	прозрачная кисть с заданной толщиной
	pPen := Gdip_CreatePen(0x90000000, r) 
	  ; меняем режим рисования. Их всего 2. 0 - Наложение рисунка(стандарт), 1 - замена. Для замены и требовался прозрачный битмап
	Gdip_SetCompositingMode(pGraphics, 1)
	  ;	делаем кольцо оббод которого чуть выходит за пределы картинки, и замещает собой пиксели картинки
	Gdip_DrawEllipse(pGraphics, pPen, -r2, -r2, Width + r, Height + r)
	Gdip_DeletePen(pPen)
	
	If 0  ;	обрамление
		 ;	Окружность вокруг вырезанного. b будет относительна Width и Height
		pPen := Gdip_CreatePen(0xffffffff, b := 10) 
		Gdip_DrawEllipse(pGraphics, pPen,  b / 2 - 1 ,  b / 2 - 1, Width - b + 1 , Height - b + 1) 
		Gdip_DeletePen(pPen)
	 
	Gdip_DrawImage(G, pBitmap2, 0, 0, Width, Height, 0, 0, Width, Height) 
	Gdip_DeleteGraphics(pGraphics)  
	Gdip_DisposeImage(pBitmap2) 
	 
	UpdateLayeredWindow(hGui, hdc, 55, 55, Width, Height, 255)
	Return

Esc::
GuiClose:
Exit:
	Gdip_DeleteGraphics(G)  
	SelectObject(hdc, obm)
	DeleteDC(hdc)
	DeleteObject(hbm) 
	Gdip_Shutdown(pToken) 
	exitapp
 
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

2

Re: AHK: Gdip - вырезание

Наверно правильнее будет регион установить. Примеров кода нет, надо гуглить.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Gdip - вырезание

Спасибо, будем посмотреть.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

4

Re: AHK: Gdip - вырезание

https://docs.microsoft.com/ru-ru/window … ping-about
Наверное как то так лучше, но пока не понял как.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

5

Re: AHK: Gdip - вырезание

Да, тоже это нашёл, так вышло:

#NoEnv

File = C:\Users\Public\Pictures\1538158694935.JPEG
Width := 200, Height := 200
Gui, New, -Caption -DPIScale +E0x80000 +hwndhGui 
Gui, Show, NA

pToken := Gdip_Startup()
hbm := CreateDIBSection(Width, Height)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
Gdip_SetSmoothingMode(G, 2)
; Gdip_SetInterpolationMode(G, 7)

pBitmap := Gdip_CreateBitmapFromFile(File)
Path := Gdip_CreatePath()
Gdip_AddPathEllipse(Path, 0, 0, Width, Height)
Gdip_SetClipPath(G, Path)
Gdip_DrawImage(G, pBitmap)

UpdateLayeredWindow(hGui, hdc, 100, 100, Width, Height)

Gdip_DeletePath(Path)
Gdip_DisposeImage(pBitmap)
Gdip_DeleteGraphics(G)
SelectObject(hdc, obm)
DeleteDC(hdc)
DeleteObject(hbm)
Gdip_Shutdown(pToken)

Но почему-то антиалиасинг не работает.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

6

Re: AHK: Gdip - вырезание

Наверное не поддерживается в Clipping.

7

Re: AHK: Gdip - вырезание

Будет время, через WIC попробую.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder