Problems displaying an image in Gdip.

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
wetware05
Posts: 750
Joined: 04 Dec 2020, 16:09

Problems displaying an image in Gdip.

25 May 2023, 07:25

Hi.

On the one hand I have the following script that puts a white border on an image and saves the result to a file:

Code: Select all

#SingleInstance, Force
#NoEnv
SetBatchLines, -1
#Include, Lib\Gdip_All.ahk

FileSelectFile, file1

If !pToken := Gdip_Startup()
pBitmapFile1 := Gdip_CreateBitmapFromFile(File1)
Width := Gdip_GetImageWidth(pBitmapFile1), Height := Gdip_GetImageHeight(pBitmapFile1)
w:=width+60
h:=height+60

pBitmap := Gdip_CreateBitmap(w, h)
G := Gdip_GraphicsFromImage(pBitmap)
pBrush := Gdip_BrushCreateSolid(0xffffffff)
Gdip_FillRectangle(G, pBrush, 0, 0, w, h)
Gdip_DeleteBrush(pBrush)

Gdip_DrawImage(G, pBitmapFile1, 30, 30, Width, Height, 0, 0, Width, Height)

Gdip_DisposeImage(pBitmapFile1)

Gdip_SaveBitmapToFile(pBitmap, "FinalImage.png")

Gdip_DisposeImage(pBitmap)
Gdip_DeleteGraphics(G)
Gdip_Shutdown(pToken)
ExitApp
Return
And on the other, this other script (partial, there is only the part of interest...), which shows an image. Not to its size, but to a ratio given a variable that determines the maximum width and height size.

Code: Select all

maxW:=500, maxH:=500
pToken := Gdip_Startup()
OnExit, GdipExit
hbm  := CreateDIBSection(maxW, maxH)
  hdc  := CreateCompatibleDC()
  obm  := SelectObject(hdc, hbm)
  G    := Gdip_GraphicsFromHDC(hdc)
  Gdip_SetInterpolationMode(G, 0)
return

displaypic:
  pBitmap := Gdip_CreateBitmapFromFile(Current.Path)
  Width   := Gdip_GetImageWidth(pBitmap)
  Height  := Gdip_GetImageHeight(pBitmap)
  ratio   := Width/Height

  if (ratio>=1)
  {
    dw:=maxW
    dh:=dw/ratio
  }
  else
  {
    dh:=maxH
    dw:=ratio*dh
  }

  Gdip_DrawImage(G, pBitmap, 0, 0, dw, dh)
  Gdip_DisposeImage(pBitmap)
  MouseGetPos, OutputVarX, OutputVarY
  UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, OutputVarY+16, dw, dh) ; preview
return

GdipExit:
  Gdip_DisposeImage(pBitmap)
  Gdip_DeleteGraphics(G)
  SelectObject(hdc, obm)
  DeleteDC(hdc)
  DeleteObject(hbm)
	Gdip_Shutdown(pToken)
	ExitApp
return
Full script at: viewtopic.php?t=90001

I've tried mixing it up, but the result is that the final image is displayed at its normal size, but cropped within the ratio designated by maxW:=500, maxH:=500 of the first line. I've come to understand Gdip a bit through what the two scripts do in common, but I don't understand how lines 4 through 8 of the second script interact with the final output.

(In my resulting script I try to calculate the size of the image with "dw" and "dh", the calculation of the image ratio, but in the end it ignores it and sticks to the actual size of the image... what I said outputs a cropped image to "dw" and "dh".)

How to put a black margin to the second script?
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Problems displaying an image in Gdip.

25 May 2023, 14:19

I think that this is what you are after.

I am using my own layered window class to do much of the stuff below.
If you look at code in the class for the 3 methods I use you should be able to make make out what is happening. If you get stuck let me know.

Code: Select all

hbm  := CreateDIBSection(maxW, maxH)
  hdc  := CreateCompatibleDC()
  obm  := SelectObject(hdc, hbm)
  G    := Gdip_GraphicsFromHDC(hdc)

.
resize by ratio.gif
resize by ratio.gif (260.64 KiB) Viewed 1148 times
.

Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib> ;<<<<<<<<<<<<<<<<<<---------------------------     gdip.ahk
;~ #Include <PopUpWindow_V2> ; At the bottom of the script 
;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchLines, -1
Gdip_Startup()




;***************************************************************
;***************************************************************
;***************************************************************
pBitmap := Gdip_CreateBitmapFromFile( "C:\Users\CivRe\OneDrive\Desktop\AHK Tools\Color Picker Mini\Screen Shots\20230525144616.png" )

Bwidth := Gdip_GetImageWidth( pBitmap )
Bheight := Gdip_GetImageHeight( pBitmap )

MaxWidth := 480
MaxHeight := 480

Margin := 10

if( BWidth > MaxWidth ){
	Width := MaxWidth
	Height := MaxWidth * ( BHeight / BWidth )
	if( Height > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )
	}
	
}else if( BHeight > MaxHeight ){
	Height := MaxHeight
	Width := MaxHeight * ( BWidth / BHeight )

}else{
	Width := BWidth
	Height := BHeight
}

w := width + 2 * Margin
h := height + 2 * Margin

;***************************************************************
;***************************************************************
;***************************************************************

Gui1 := New PopUpWindow( { AutoShow: 1 , X: "center" , Y: "center" , W: w , H: h , Options: " -DPIScale +AlwaysOnTop " } )
Gui1.PaintBackground( color := "0x99000000" , AutoUpdate := 0 )
Gui1.DrawBitmap( pBitmap , { X: margin , Y: margin , W: Width , H: Height } , dispose := 0 , AutoUpdate := 1 )

;***************************************************************
;***************************************************************
;***************************************************************

return
GuiClose:
GuiContextMenu:
*ESC::ExitApp

RALT::PopUpWindow.Helper()




;Layered Window Class
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
class PopUpWindow	{
;PopUpWindow v2.2
;Date Written: Oct 28th, 2021
;Last Edit: Feb 7th, 2022 :Changed the trigger method.
;Written By: Hellbent aka CivReborn
;SpcThanks: teadrinker , malcev 
	static Index := 0 , Windows := [] , Handles := [] , EditHwnd , HelperHwnd
	__New( obj := "" ){
		This._SetDefaults()
		This.UpdateSettings( obj )
		This._CreateWindow()
		This._CreateWindowGraphics()
		if( This.AutoShow )
			This.ShowWindow( This.Title )
	}
	_SetDefaults(){
		This.X := 10
		This.Y := 10
		This.W := 10
		This.H := 10
		This.Smoothing := 2
		This.Options := " -DPIScale +AlwaysOnTop "
		This.AutoShow := 0
		This.GdipStartUp := 0
		This.Title := ""
		
		This.Controls := []
		This.Handles := []
		This.Index := 0 
	}
	AddTrigger( obj ){
		local k , v , cc , bd
		
		This.Controls[ ++This.Index ] := { 	X:		10
										,	Y:		10
										,	W:		10
										,	H:		10	}
		for k, v in obj
			This.Controls[ This.Index ][ k ] := obj[ k ] 
		cc := This.Controls[ This.Index ]
		Gui, % This.Hwnd ":Add", Text, % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H " hwndhwnd"
		This.Handles[ hwnd ] := This.Index
		This.Controls[ This.Index ].Hwnd := hwnd
		
		if( IsObject( cc.Label ) ){
			bd := cc.Label
			GuiControl, % This.Hwnd ":+G" , % hwnd , % bd
		}else{
			bd := This._TriggerCall.Bind( This )
			GuiControl, % This.Hwnd ":+G" , % hwnd , % bd
		}
		return hwnd
		
	}
	_TriggerCall(){
		MouseGetPos,,,, ctrl, 2
		Try
			;~ SetTimer, % This.Controls[ This.Handles[ ctrl ] ].Label, -0
			gosub, % This.Controls[ This.Handles[ ctrl ] ].Label
		
				
	}
	DrawTriggers( color := "0xFFFF0000" , AutoUpdate := 0 ){
		local brush , cc 
		Brush := Gdip_BrushCreateSolid( color ) 
		Gdip_SetSmoothingMode( This.G , 3 )
		loop, % This.Controls.Length()	{
			cc := This.Controls[ A_Index ]
			Gdip_FillRectangle( This.G , Brush , cc.x , cc.y , cc.w , cc.h )
		
		}
		Gdip_DeleteBrush( Brush )
		Gdip_SetSmoothingMode( This.G , This.Smoothing )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	UpdateSettings( obj := "" , UpdateGraphics := 0 ){
		local k , v
		if( IsObject( obj ) )
			for k, v in obj
				This[ k ] := obj[ k ]
		( This.X = "Center" ) ? ( This.X := ( A_ScreenWidth - This.W ) / 2 ) 	
		( This.Y = "Center" ) ? ( This.Y := ( A_ScreenHeight - This.H ) / 2 ) 	
		if( UpdateGraphics ){
			This._DestroyWindowsGraphics()
			This._CreateWindowGraphics()
		}
	}
	_CreateWindow(){
		local hwnd
		Gui , New, % " +LastFound +E0x80000 hwndhwnd -Caption  " This.Options
		PopUpWindow.Index++
		This.Index := PopUpWindow.Index
		PopUpWindow.Windows[ PopUpWindow.Index ] := This
		This.Hwnd := hwnd
		PopUpWindow.Handles[ hwnd ] := PopUpWindow.Index
		if( This.GdipStartUp && !PopUpWindow.pToken )
			PopUpWindow.pToken := GDIP_STARTUP()
	}
	_DestroyWindowsGraphics(){
		Gdip_DeleteGraphics( This.G )
		SelectObject( This.hdc , This.obm )
		DeleteObject( This.hbm )
		DeleteDC( This.hdc )
	}
	_CreateWindowGraphics(){
		This.hbm := CreateDIBSection( This.W , This.H )
		This.hdc := CreateCompatibleDC()
		This.obm := SelectObject( This.hdc , This.hbm )
		This.G := Gdip_GraphicsFromHDC( This.hdc )
		Gdip_SetSmoothingMode( This.G , This.Smoothing )
	}
	ShowWindow( Title := "" ){
		Gui , % This.Hwnd ":Show", % "x" This.X " y" This.Y " w" This.W " h" This.H " NA", % Title
	}
	HideWindow(){
		Gui , % This.Hwnd ":Hide",
	}
	UpdateWindow( alpha := 255 ){
		UpdateLayeredWindow( This.hwnd , This.hdc , This.X , This.Y , This.W , This.H , alpha )
	}
	ClearWindow( AutoUpdate := 0 , Color := "" ){
		if( color != "" )
			Gdip_GraphicsClear( This.G , color )
		else
			Gdip_GraphicsClear( This.G )
		if( Autoupdate )
			This.UpdateWindow()
	}
	DrawBitmap( pBitmap , obj , dispose := 1 , AutoUpdate := 0 ){
		Gdip_DrawImage( This.G , pBitmap , obj.X , obj.Y , obj.W , obj.H )
		if( dispose )
			Gdip_DisposeImage( pBitmap )
		if( Autoupdate )
			This.UpdateWindow()
	}
	PaintBackground( color := "0xFF000000" , AutoUpdate := 0 ){
		if( isObject( color ) ){
			Brush := Gdip_BrushCreateSolid( ( color.HasKey( "Color" ) ) ? ( color.Color ) : ( "0xFF000000" ) ) 
			if( color.Haskey( "Round" ) )
				Gdip_FillRoundedRectangle( This.G , Brush , color.X , color.Y , color.W , color.H , color.Round )
			else
				Gdip_FillRectangle( This.G , Brush , color.X , color.Y , color.W , color.H ) 
		}else{
			Brush := Gdip_BrushCreateSolid( color ) 
			Gdip_FillRectangle( This.G , Brush , -1 , -1 , This.W + 2 , This.H + 2 ) 
		}
		Gdip_DeleteBrush( Brush )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	DeleteWindow( GDIPShutdown := 0 ){
		Gui, % This.Hwnd ":Destroy"
		SelectObject( This.hdc , This.obm )
		DeleteObject( This.hbm )
		DeleteDC( This.hdc )
		Gdip_DeleteGraphics( This.G )
		hwnd := This.Hwnd
		for k, v in PopUpWindow.Windows[ Hwnd ]
			This[k] := ""
		PopUpWindow.Windows[ Hwnd ] := ""
		if( GDIPShutdown ){
			Gdip_Shutdown( PopUpWindow.pToken )
			PopUpWindow.pToken := ""
		}
	}
	_OnClose( wParam ){
		if( wParam = 0xF060 ){	;SC_CLOSE ;[ clicking on the gui close button ]
			Try{
				Gui, % PopUpWindow.HelperHwnd ":Destroy"
				SoundBeep, 555
			}
		}
	}
	CreateCachedBitmap( pBitmap , Dispose := 0 ){
		local pCachedBitmap
		if( This.CachedBitmap )
			This.DisposeCachedbitmap()
		DllCall( "gdiplus\GdipCreateCachedBitmap" , "Ptr" , pBitmap , "Ptr" , this.G , "PtrP" , pCachedBitmap )
		This.CachedBitmap := pCachedBitmap
		if( Dispose )
			Gdip_DisposeImage( pBitmap )
	}
	DrawCachedBitmap( AutoUpdate := 0 ){
		DllCall( "gdiplus\GdipDrawCachedBitmap" , "Ptr" , this.G , "Ptr" , This.CachedBitmap , "Int" , 0 , "Int" , 0 )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	DisposeCachedbitmap(){
		DllCall( "gdiplus\GdipDeleteCachedBitmap" , "Ptr" , This.CachedBitmap )
	}
	Helper(){
		local hwnd , MethodList := ["__New","UpdateSettings","ShowWindow","HideWindow","UpdateWindow","ClearWindow","DrawBitmap","PaintBackground","DeleteWindow" , "AddTrigger" , "DrawTriggers", "CreateCachedBitmap" , "DrawCachedBitmap" , "DisposeCachedbitmap" ]
		Gui, New, +AlwaysOnTop +ToolWindow +HwndHwnd
		PopUpWindow.HelperHwnd := hwnd
		Gui, Add, Edit, xm ym w250 r1 Center hwndhwnd, Gui1
		PopUpWindow.EditHwnd := hwnd
		loop, % MethodList.Length()	
			Gui, Add, Button, xm y+1 w250 r1 gPopUpWindow._HelperClip, % MethodList[ A_Index ]
		Gui, Show,,
		OnMessage( 0x112 , This._OnClose.Bind( hwnd ) )
	}
	_HelperClip(){
		local ClipList 
		
		GuiControlGet, out, % PopUpWindow.HelperHwnd ":", % PopUpWindow.EditHwnd	
		
		ClipList := 		{ 	__New: 					" := New PopUpWindow( { AutoShow: 1 , X: 0 , Y: 0 , W: A_ScreenWidth , H: A_ScreenHeight , Options: "" -DPIScale +AlwaysOnTop "" } )"
							,	UpdateSettings:			".UpdateSettings( { X: """" , Y: """" , W: """" , H: """" } , UpdateGraphics := 0 )"
							,	ShowWindow:				".ShowWindow( Title := """" )"
							,	HideWindow:				".HideWindow()"
							,	UpdateWindow:			".UpdateWindow()"
							,	ClearWindow:			".ClearWindow( AutoUpdate := 0 )"
							,	DrawBitmap:				".DrawBitmap( pBitmap := """" , { X: 0 , Y: 0 , W: " Out ".W , H: " Out ".H } , dispose := 1 , AutoUpdate := 0 )"
							,	PaintBackground:		".PaintBackground( color := ""0xFF000000"" , AutoUpdate := 0 )  "  ";{ Color: ""0xFF000000"" , X: 2 , Y: 2 , W: " Out ".W - 4 , H: " Out ".H - 4 , Round: 10 }"
							,	DeleteWindow:			".DeleteWindow( GDIPShutdown := 0 )"
							,	AddTrigger:				".AddTrigger( { X: """" , Y: """" , W: """" , H: """" , Value: """" , Label: """" } )"	
							,	DrawTriggers:			".DrawTriggers( color := ""0xFFFF0000"" , AutoUpdate := 0 )"	
							,	CreateCachedBitmap:		".CreateCachedBitmap( pBitmap , Dispose := 0 )"	
							,	DrawCachedBitmap: 		".DrawCachedBitmap( AutoUpdate := 0 )"	
							,	DisposeCachedbitmap:	".DisposeCachedbitmap()"	}
							
		clipboard := Out ClipList[ A_GuiControl ]
		
	}
}

wetware05
Posts: 750
Joined: 04 Dec 2020, 16:09

Re: Problems displaying an image in Gdip.

25 May 2023, 14:55

Hi.

What the original script does: fit the image to a height and width limit size, to create a preview of the image.

I lost one of the variations I worked on last night (the one that cropped the image). And trying to recreate it today (with the script below adding "original script" with the mixed "add a white border" part) now outputs the full image, but the border with the size of the original image, not respecting that The width and height limit for the preview should be adapted.

I "read" and understand part of the Gdpi code (by logic, not by knowledge), but I don't know what the variable "G" does (The variable in which the process performed on the graph in Gdpi is stored in memory?) It can there be two G variables (G and G1) or is that wrong?

Help or guidance please.

Code: Select all

 maxStr:=200, maxW:=500, maxH:=500
 pToken := Gdip_Startup()
  OnExit, GdipExit

  hbm  := CreateDIBSection(maxW, maxH)
  hdc  := CreateCompatibleDC()
  obm  := SelectObject(hdc, hbm)
  G    := Gdip_GraphicsFromHDC(hdc)
  Gdip_SetInterpolationMode(G, 0)
return

displaypic:
  pBitmap := Gdip_CreateBitmapFromFile(Current.Path)
  Width   := Gdip_GetImageWidth(pBitmap)
  Height  := Gdip_GetImageHeight(pBitmap)
  ratio   := Round(Width/Height)

  if (ratio>=1)
  {
    dw:=Round(maxW)
    dh:=Round(dw/ratio)
  }
  else
  {
    dh:=Round(MaxH)
    dw:=Round(ratio*dh)
  }
   
  ;-----------Script 2, create Border-----------  
  w:=dw+10
  h:=dh+10 
  pBitmap1 := Gdip_CreateBitmap(w, h)
  G1 := Gdip_GraphicsFromImage(pBitmap1)
  pBrush := Gdip_BrushCreateSolid(0xffffffff)
  Gdip_FillRectangle(G, pBrush, 0, 0, w, h)
  Gdip_DeleteBrush(pBrush)
  ;--------------------------------------------------
  
  Gdip_DrawImage(G, pBitmap, 5, 5, dw, dh, 0, 0, dw, dh) ; Script 2
    ;Gdip_DrawImage(G, pBitmap, 0, 0, dw, dh) ; Original

  Gdip_DisposeImage(pBitmap)
   MouseGetPos, OutputVarX, OutputVarY
  UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, (OutputVarY-dh)-16, dw, dh)
Complete script. To see previous images, which work both in Total Commander x32 and x64, as well as on the desktop or Explorer (adapted to a single monitor and do not go off screen, pending changes for multiple monitors):

Code: Select all

; Mouse over to the file to preview the content without clicking. Support ahk,txt,ini,jpg,jpeg,png,bmp,tif format.
; You must enable "show file ext name" in explorer.
; 鼠标移动到文件上面,不用点击即可预览内容。支持 ahk,txt,ini,jpg,jpeg,png,bmp,tif 格式。
; 需要在 资源管理器-显示 中勾选 “文件扩展名” 选项。
;https://www.autohotkey.com/boards/viewtopic.php?t=90001
#Requires AutoHotkey v1.1.33
SetBatchLines, -1
CoordMode, Mouse, Screen
maxStr:=200 ;, maxW:=1500, maxH:=1500
;maxStr:=200, maxW:=500, maxH:=500
XSize:= A_ScreenWidth
YSize:= A_ScreenHeight
Global NoW
NoW:=""


if !FileExist("Config.ini")
  {
  IniWrite, 500, Config.ini, Preview_TCM, maxW
  IniWrite, 500, Config.ini, Preview_TCM, maxH
  ;IniWrite, Window7, Config.ini, Preview_TCM, NoW
  }

If !maxW
 {
  IniRead, maxW, Config.ini, Preview_TCM, maxW
 }
If !maxH
 {
  IniRead, maxH, Config.ini, Preview_TCM, maxH
 }

gosub, init
SetTimer, preview, 50
return

preview:
  Current := GetFileUnderMouse()

  if (Displayed != Current.Path)
  {
    Displayed := Current.Path
    Ext       := Current.Ext
    if Ext in ahk,txt,ini
    {
      UpdateLayeredWindow(hPreview, hdc, , , , , 0)
      File := FileOpen(Current.Path, "r")
      btt(File.Read(maxStr),,,,"Style5")
      File.Close()
    }
    else if Ext in jpg,jpeg,png,bmp,tif
    {
      btt()
      gosub, displaypic
    }
    else
    {
      btt()
      UpdateLayeredWindow(hPreview, hdc, , , , , 0)
    }
  }
return

init:
  ; close system file info tip.
  RegRead, ShowInfoTip, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip
  RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, 0
  
  Gui, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
  Gui, Show, NA

  pToken := Gdip_Startup()
  OnExit, GdipExit

  hbm  := CreateDIBSection(maxW, maxH)
  hdc  := CreateCompatibleDC()
  obm  := SelectObject(hdc, hbm)
  G    := Gdip_GraphicsFromHDC(hdc)
  Gdip_SetInterpolationMode(G, 0)
return

displaypic:
  pBitmap := Gdip_CreateBitmapFromFile(Current.Path)
  Width   := Gdip_GetImageWidth(pBitmap)
  Height  := Gdip_GetImageHeight(pBitmap)
  ratio   := Round(Width/Height)

  if (ratio>=1)
  {
    dw:=Round(maxW)
    dh:=Round(dw/ratio)
  }
  else
  {
    dh:=Round(MaxH)
    dw:=Round(ratio*dh)
  }
   
  
  w:=dw+10
  h:=dh+10 
  pBitmap1 := Gdip_CreateBitmap(w, h)
  G1 := Gdip_GraphicsFromImage(pBitmap1)
  pBrush := Gdip_BrushCreateSolid(0xffffffff)
  Gdip_FillRectangle(G, pBrush, 0, 0, w, h)
  Gdip_DeleteBrush(pBrush)
  
  
  Gdip_DrawImage(G, pBitmap, 5, 5, dw, dh, 0, 0, dw, dh)
  
  
  ;Gdip_DrawImage(G, pBitmap, 0, 0, dw, dh)
  Gdip_DisposeImage(pBitmap)
  
  MouseGetPos, OutputVarX, OutputVarY
  
  NewPos:=0
  PosY:= OutputVarY-dh
    If PosY < 0
    {
     ;StringTrimLeft, NPosY, PosY, 1
     ;OutPutVarY:= OutPutVarY+NPosY
     NewPos:=1
    }
  
  PosX:= OutputVarx+dw
    
    If PosX > %XSize%
    {
     NPosX:= PosX-XSize
     OutPutVarX:= OutPutVarX-NPosX
     ;NewPos:=1
    }
    
  If NewPos=0
   {
   UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, (OutputVarY-dh)-16, dw, dh)
   ;UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, (OutputVarY-dh)-6, dw, dh)
   }
  If NewPos=1
   {
   UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, OutputVarY+16, dw, dh)
   }
return

GdipExit:
  RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, %ShowInfoTip%
  Gdip_DisposeImage(pBitmap)
  Gdip_DeleteGraphics(G)
  SelectObject(hdc, obm)
  DeleteDC(hdc)
  DeleteObject(hbm)
	Gdip_Shutdown(pToken)
	ExitApp
return

^p::
Pause , Toggle
Return

; https://www.autohotkey.com/boards/viewtopic.php?t=51788
; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=69925
GetFileUnderMouse()
{
  static Windows:=ComObjCreate("Shell.Application").Windows

  MouseGetPos, , , hwnd, CtrlClass
  WinGetClass, WinClass, ahk_id %hwnd%
  
try if WinActive("ahk_exe TOTALCMD.exe") or WinActive("ahk_exe TOTALCMD64.exe")
{
If (WinActive("ahk_exe TOTALCMD.exe") || State=2)
{
Gosub, Find_Control
}

If (WinActive("ahk_exe TOTALCMD64.exe") || State=1)
{
Gosub, Find_Control64
}

If !NoW
 {
  If WinActive("ahk_exe TOTALCMD.exe")
  {
   Gosub, Find_Control
  }
 If WinActive("ahk_exe TOTALCMD64.exe")
  {
   Gosub, Find_Control64
  }
 }

GetKeyState, state, Ctrl
 if (state = "D")
 {
  ret:= UIA_Interface()
 
  ControlGetText sPath, % NoW
  stringRight, RLast, sPath, 1
  sPath:=StrReplace(sPath,">","")
  Element := ret.ElementFromPoint()
  itemName := Element.GetCurrentPropertyValue(30005)
  if (itemName == "")
	itemName := "No 'Name'"

  RegExMatch(itemName, "^[^\t]*", Reg)
  FullPath:= sPath Reg
    
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := sPath "\" Reg
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}
Else
  try if (WinClass = "CabinetWClass" && CtrlClass = "DirectUIHWND2")
  {
    oAcc := Acc_ObjectFromPoint()
    Name := Acc_Parent(oAcc).accValue(0)
    NonNull(Name, oAcc.accValue(0))
    
    if (Name="")
      return

    for window in Windows
      if (window.hwnd = hwnd)
      {
        FolderPath := RegExReplace(window.Document.Folder.Self.Path, "(\w+?\:)\\$", "$1") ; “d:\” 转换为 “d:”

        SplitPath, Name, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := FolderPath "\" Name
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt

        return, ret
      }
  }
  else if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    oAcc := Acc_ObjectFromPoint(ChildID)
    Name := ChildID ? oAcc.accName(ChildID) : ""

    if (Name="")
      return

    SplitPath, Name, , , OutExtension, OutNameNoExt
    ret := {}
    ret.Path := A_Desktop "\" Name
    ret.Ext  := OutExtension
    ret.Name := OutNameNoExt

    return, ret
  }
}

Acc_Init() {
	Static h
	If Not h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "") {
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}

^!s::
Xpos:= Floor((A_ScreenWidth/2)-450)
Ypos:= Floor((A_ScreenHeight/2)-200)
;Gui, Search:+HwndGuiID	
Gui, Size: Add, Button, x225 y16 w65 h20 GNewSize, OK
Gui, Size: Add, Button, x225 y46 w65 h20 gCancel, Cancel
Gui, Size: Font, S9 Bold, Verdana
Gui, Size: Add, Text, x10 y16 w90 h20, Max. Width:
Gui, Size: Add, edit, x100 y16 w100 h20 vFmaxW
Gui, Size: Add, Text, x10 y46 w90 h20, Max.   High:
Gui, Size: Add, edit, x100 y46 w100 h20 vFmaxH
Gui, Size: Show, x%xpos% y%ypos% h80 w300, Size_P
Return

Cancel:
Gui, Size: Destroy
Return

NewSize:
Gui, Size: Submit
If !FmaxW
 {
  MaxW:=500
 }
Else MaxW:=FmaxW
IniWrite, %MaxW%, Config.ini, Preview_TCM, maxW

MaxW:=FmaxW
If !FmaxH
 {
  MaxH:=500
 }
Else MaxH:=FmaxH
IniWrite, %MaxH%, Config.ini, Preview_TCM, maxH
Gui, Size: Destroy
Return

;^F8::
Find_Control:
Now:=""
Loop, 30
 {
 NewWin:= "TMyPanel" A_Index
 ControlGetText PPath, % NewWin
 Ello:= % NewWin . " " . PPath
 StringRight, RLast, PPath, 1
 If RLast=>
   {
   NoW:= NewWin
   State=1
   Break 
   }
 }
Return

;^F9::
Find_Control64:
Loop, 30
 {
 NewWin:= "Window" A_Index
 ControlGetText PPath, % NewWin
 Ello:= % NewWin . " " . PPath
 StringRight, RLast, PPath, 1
 If RLast=>
   {
   NoW:= NewWin
   State=2
   Break 
   }
 }
Return

#Include <NonNull>
#Include <Gdip_All>
Original: viewtopic.php?t=90001
wetware05
Posts: 750
Joined: 04 Dec 2020, 16:09

Re: Problems displaying an image in Gdip.

25 May 2023, 15:01

ah!, Hellbent

I had not read your message. I was writing mine. I'm going to read and try. Thank you!!! :thumbup:
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Problems displaying an image in Gdip.

25 May 2023, 15:15

but I don't know what the variable "G" does (The variable in which the process performed on the graph in Gdpi is stored in memory?) It can there be two G variables (G and G1) or is that wrong?
"G" is the "graphics" layer/element of a bitmap.
"HBM" would suggest that it is an HBitmap, so "G" is the graphics layer of the HBitmap.

If you don't want to draw directly to the window you should just draw your newly sized image on a pBitmap and then draw the new pbitmap on your layered window.

Code: Select all


NewImage := CreateNewSizedBitmap()

;ToolTip, % NewImage.Bitmap "`n" NewImage.W "`n" NewImage.H

;Now you draw the new bitmap on your layered window.
Gdip_DrawImage( Graphics , NewImage.Bitmap , 10 , 10 , NewImage.W  , NewImage.H )


;***********************************
CreateNewSizedBitmap(){
	
pBitmap := Gdip_CreateBitmapFromFile( "C:\Users\CivRe\OneDrive\Desktop\AHK Tools\Color Picker Mini\Screen Shots\20230525144616.png" )

Bwidth := Gdip_GetImageWidth( pBitmap )
Bheight := Gdip_GetImageHeight( pBitmap )

MaxWidth := 480
MaxHeight := 480

Margin := 10

	if( BWidth > MaxWidth ){
		Width := MaxWidth
		Height := MaxWidth * ( BHeight / BWidth )
		if( Height > MaxHeight ){
			Height := MaxHeight
			Width := MaxHeight * ( BWidth / BHeight )
		}
	
	}else if( BHeight > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )

	}else{
		Width := BWidth
		Height := BHeight
	}

	w := width + 2 * Margin
	h := height + 2 * Margin
	
	;Output
	obj := {}
	obj.W := w
	obj.H := h
	obj.BitMap :=  Gdip_CreateBitmap( w , h )
	Graphics := Gdip_GraphicsFromImage( obj.BitMap )
	Gdip_SetInterpolationMode( Graphics  , 0)
	
	pBrush := Gdip_BrushCreateSolid(0xffffffff)
	Gdip_FillRectangle(G, pBrush, 0, 0, w, h)
	Gdip_DeleteBrush(pBrush)
	
	Gdip_DrawImage( Graphics , pBitmap , Margin , Margin , Width , Height )
	
	Gdip_DeleteGraphics( Graphics  )
	return obj
	
}


wetware05
Posts: 750
Joined: 04 Dec 2020, 16:09

Re: Problems displaying an image in Gdip.

25 May 2023, 15:21

Hi, @Hellbent


I wouldn't know how to adapt your script that I'm working with. It is a preview image viewer:



I don't quite understand how this script works, because it defines a Gui, but empty (lines 69 and 70, in the second script above). And the image is displayed in the line UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, (OutputVarY-dh)-16, dw, dh).

It would be faster for me to correct the mix of the two scripts. Perhaps by chance, by trial and error, in the end I achieve the desired result, but someone who knows how to read the code surely knows where the problem is with the naked eye.

(Our messages have crossed again, I'll look at what you shared. Thank you.)
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Problems displaying an image in Gdip.

25 May 2023, 18:06

This is the first code without the class.

You just call the createpreviewwindow() function and then when you want to display a resized image you call the showpreview() function.

Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib> ;<<<<<<<<<<<<<<<<<<---------------------------     gdip.ahk
;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchLines, -1
Gdip_Startup()

PreviewWindow := CreatePreviewWindow( MaxWidth := 500 , MaxHeight := 500 ) ;Create the preview window

path := "C:\Users\CivRe\OneDrive\Desktop\AHK Tools\Color Picker Mini\Screen Shots\20230525144616.png" ;the path to an image file

ShowPreview( Path , PreviewWindow ) ;Resize and draw the image on the window and display it.

return
GuiClose:
GuiContextMenu:
*ESC::ExitApp

F1::
	Path := Clipboard
	ShowPreview( Path , PreviewWindow )
	return

CreatePreviewWindow( Width , Height ){
	local Obj := {}
	Gui, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
	Obj.Hwnd := hPreview
	Gui, Show, NA
	Obj.Width := Width
	Obj.Height := Height
	Obj.hbm  := CreateDIBSection( Obj.Width , Obj.Height )
	Obj.hdc  := CreateCompatibleDC()
	Obj.obm  := SelectObject( Obj.hdc , Obj.hbm )
	Obj.G    := Gdip_GraphicsFromHDC( Obj.hdc )
	Gdip_SetInterpolationMode( Obj.G , 0)
	
	return obj
}

ShowPreview( Path , PreviewWindow ){
	pBitmap := Gdip_CreateBitmapFromFile( path )
	Bwidth := Gdip_GetImageWidth( pBitmap )
	Bheight := Gdip_GetImageHeight( pBitmap )
	
	Margin := 10
	MaxWidth := PreviewWindow.Width - 2 * Margin
	MaxHeight := PreviewWindow.Height - 2 * Margin

	if( BWidth > MaxWidth ){
		Width := MaxWidth
		Height := MaxWidth * ( BHeight / BWidth )
		if( Height > MaxHeight ){
			Height := MaxHeight
			Width := MaxHeight * ( BWidth / BHeight )
		}
		
	}else if( BHeight > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )

	}else{
		Width := BWidth
		Height := BHeight
	}
	pBrush := Gdip_BrushCreateSolid( "0xFFFFFFFF" )
	GDIP_FillRectangle( PreviewWindow.G , pBrush , 0 , 0 , PreviewWindow.Width , PreviewWindow.Height )
	Gdip_DeleteBrush( Brush )
	Gdip_DrawImage( PreviewWindow.G , pBitmap , ( PreviewWindow.Width - width ) / 2 , ( PreviewWindow.Height - height ) / 2 , width , height )
	CoordMode, Mouse, Screen
	MouseGetPos, x, y
	UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x + 16 , y + 16 , PreviewWindow.Width , PreviewWindow.Height )
	Gdip_DisposeImage( pBitmap )
}

wetware05
Posts: 750
Joined: 04 Dec 2020, 16:09

Re: Problems displaying an image in Gdip.

25 May 2023, 18:08

Hi.

I've tried mixing the latest Hellbent script I'm working with and got nothing.

The closest I've come is by mixing the scripts shared by me. With this result.

Image

The process goes more or less well, while the margin above and to the left is correct, but strangely the size of the frame is that of the original image, when during the whole process of creating the rectangle it is "told" stick to the size of the reduced version. There is some error that does not come to light.

I still think that the "secret" is in these lines, which do not apply to the rectangle.

Code: Select all

hbm  := CreateDIBSection(maxW, maxH)
  hdc  := CreateCompatibleDC()
  obm  := SelectObject(hdc, hbm)
  G    := Gdip_GraphicsFromHDC(hdc)
  Gdip_SetInterpolationMode(G, 0)
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Problems displaying an image in Gdip.

25 May 2023, 18:22

Hi @wetware05 , try my latest code.

It has a function to create a display window and a function to draw a resized image on the window.


I had tried the code on the page you directed to but it seems to be missing a number of functions.
wetware05
Posts: 750
Joined: 04 Dec 2020, 16:09

Re: Problems displaying an image in Gdip.

25 May 2023, 18:47

Hellbent wrote:
25 May 2023, 18:22
Hi @wetware05 , try my latest code.
It has a function to create a display window and a function to draw a resized image on the window.
I had tried the code on the page you directed to but it seems to be missing a number of functions.
Hi.
But I don't know how to integrate it into the script I have, which I didn't write, and I don't understand it well. It's "all or nothing", I would say, either the changes are adapted to that script or you have to do it all over again. Look at its simple structure by routines, "preview:", "init:" "displaypic:" "GdipExit:", plus the functions that are basically to know the file under the mouse and the full path. If one doesn't stick to its structure, the whole script falls apart.

Tomorrow I will review it again, to see if I can adapt it. I'm going to bed. Perhaps doing everything again except the functions of the object under the mouse.

Download functions. The script has changed to what I have shared above: https://mega.nz/file/5RAUhCTR#GNZ7-6tbjYXVTIQoGc_4oepQIbQtNysO5IaAyVBihTo
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Problems displaying an image in Gdip.

25 May 2023, 19:15

I don't download stuff so I can't run it, but I did have another look at that code and I think that all you need to do to edit mine in is to first replace the init routine with the new code.

OLD:

Code: Select all

init:
  ; close system file info tip.
  RegRead, ShowInfoTip, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip
  RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, 0

  Gui, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
  Gui, Show, NA

  pToken := Gdip_Startup()
  OnExit, GdipExit

  hbm  := CreateDIBSection(maxW, maxH)
  hdc  := CreateCompatibleDC()
  obm  := SelectObject(hdc, hbm)
  G    := Gdip_GraphicsFromHDC(hdc)
  Gdip_SetInterpolationMode(G, 0)
return
NEW:

Code: Select all


init:
	; close system file info tip.
	RegRead, ShowInfoTip, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip
	RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, 0
	pToken := Gdip_Startup()
	OnExit, GdipExit
	PreviewWindow := CreatePreviewWindow( MaxWidth := 500 , MaxHeight := 500 )
return

CreatePreviewWindow( Width , Height ){
	local Obj := {}
	Gui, New, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
	Obj.Hwnd := hPreview
	Gui, Show, NA
	Obj.Width := Width
	Obj.Height := Height
	Obj.hbm  := CreateDIBSection( Obj.Width , Obj.Height )
	Obj.hdc  := CreateCompatibleDC()
	Obj.obm  := SelectObject( Obj.hdc , Obj.hbm )
	Obj.G    := Gdip_GraphicsFromHDC( Obj.hdc )
	Gdip_SetInterpolationMode( Obj.G , 0)
	
	return obj
}
And then you change the gosub in this old code and change a few things in the Update func.

OLD:

Code: Select all

preview:
  Current := GetFileUnderMouse()

  if (Displayed != Current.Path)
  {
    Displayed := Current.Path
    Ext       := Current.Ext
    if Ext in ahk,txt,ini
    {
      UpdateLayeredWindow( hPreview , hdc, , , , , 0)
      File := FileOpen(Current.Path, "r")
      btt(File.Read(maxStr),,,,"Style5")
      File.Close()
    }
    else if Ext in jpg,jpeg,png,bmp,tif
    {
      btt()
      gosub, displaypic
    }
    else
    {
      btt()
      UpdateLayeredWindow(hPreview, hdc, , , , , 0)
    }
  }
return

NEW:

Code: Select all

preview:
  Current := GetFileUnderMouse()

  if (Displayed != Current.Path)
  {
    Displayed := Current.Path
    Ext       := Current.Ext
    if Ext in ahk,txt,ini
    {
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0) ;<<<--
      File := FileOpen(Current.Path, "r")
      btt(File.Read(maxStr),,,,"Style5")
      File.Close()
    }
    else if Ext in jpg,jpeg,png,bmp,tif
    {
      btt() ;<<--No idea what this does
      ShowPreview( Current.Path , PreviewWindow ) ;<<<<<----------
    }
    else
    {
      btt()
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)  ;<<<--
    }
  }
return
Last you replace this old code with the new code.

OLD:

Code: Select all

displaypic:
  pBitmap := Gdip_CreateBitmapFromFile(Current.Path)
  Width   := Gdip_GetImageWidth(pBitmap)
  Height  := Gdip_GetImageHeight(pBitmap)
  ratio   := Width/Height

  if (ratio>=1)
  {
    dw:=maxW
    dh:=dw/ratio
  }
  else
  {
    dh:=maxH
    dw:=ratio*dh
  }

  Gdip_DrawImage(G, pBitmap, 0, 0, dw, dh)
  Gdip_DisposeImage(pBitmap)
  MouseGetPos, OutputVarX, OutputVarY
  UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, OutputVarY+16, dw, dh)
return
NEW:

Code: Select all

ShowPreview( Path , PreviewWindow ){
	pBitmap := Gdip_CreateBitmapFromFile( path )
	Bwidth := Gdip_GetImageWidth( pBitmap )
	Bheight := Gdip_GetImageHeight( pBitmap )
	
	Margin := 10
	MaxWidth := PreviewWindow.Width - 2 * Margin
	MaxHeight := PreviewWindow.Height - 2 * Margin

	if( BWidth > MaxWidth ){
		Width := MaxWidth
		Height := MaxWidth * ( BHeight / BWidth )
		if( Height > MaxHeight ){
			Height := MaxHeight
			Width := MaxHeight * ( BWidth / BHeight )
		}
		
	}else if( BHeight > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )

	}else{
		Width := BWidth
		Height := BHeight
	}
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( "0xFFFFFFFF" )
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , PreviewWindow.Width , PreviewWindow.Height )
	Gdip_DeleteBrush( Brush )
	Gdip_DrawImage( PreviewWindow.G , pBitmap , ( PreviewWindow.Width - width ) / 2 , ( PreviewWindow.Height - height ) / 2 , width , height )
	CoordMode, Mouse, Screen
	MouseGetPos, x, y
	UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x + 16 , y + 16 , PreviewWindow.Width , PreviewWindow.Height )
	Gdip_DisposeImage( pBitmap )
}

****EDIT****

The ShowPreview() Function above will always show a 500 x 500 window with the image resized and centered.

for example.

.
20230525225506.png
20230525225506.png (79.25 KiB) Viewed 973 times
.


If you just want a border to wrap the outside of the image use this code instead.

for example.

.
20230525225519.png
20230525225519.png (59.7 KiB) Viewed 973 times
.

Code: Select all

ShowPreview( Path , PreviewWindow ){
	
	pBitmap := Gdip_CreateBitmapFromFile( path )
	Bwidth := Gdip_GetImageWidth( pBitmap )
	Bheight := Gdip_GetImageHeight( pBitmap )
	
	Margin := 10
	MaxWidth := PreviewWindow.Width - 2 * Margin
	MaxHeight := PreviewWindow.Height - 2 * Margin

	if( BWidth > MaxWidth ){
		Width := MaxWidth
		Height := MaxWidth * ( BHeight / BWidth )
		
		if( Height > MaxHeight ){
			Height := MaxHeight
			Width := MaxHeight * ( BWidth / BHeight )
		}
		
	}else if( BHeight > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )

	}else{
		Width := BWidth
		Height := BHeight
	}
	Gdip_GraphicsClear( PreviewWindow.G ) ;clear the graphics to start with a fresh canvas to draw on
	Brush := Gdip_BrushCreateSolid( "0x99000000" ) ; create a brush and give it a color (AARRGGBB)
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , width + 2 * Margin , height + 2 * Margin ) ;use the brush to fill a rectangle on the graphics
	Gdip_DeleteBrush( Brush ) ;delete the brush to free the memory ( alt is to have a "Memory Leak" )
	Gdip_DrawImage( PreviewWindow.G , pBitmap , Margin , Margin , width , height ) ;Draw the resized image on the graphics
	CoordMode, Mouse, Screen ;set coordmode to the screen
	MouseGetPos, x, y ;get the current mouse position
	UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x + 16 , y + 16 , PreviewWindow.Width , PreviewWindow.Height ) ;draw the graphics onto the window and reposition it at an offset of the cursor.
	Gdip_DisposeImage( pBitmap ) ;delete the bitmap to free memory.
}
wetware05
Posts: 750
Joined: 04 Dec 2020, 16:09

Re: Problems displaying an image in Gdip.

26 May 2023, 04:46

Thank you very much Hellbent for all your effort. :salute:

It doesn't work for something basic, that your code is functions and you can't call functions inside routines (or it's the other way around). I'm going to try to make them not functions and see what happens. Or the other way around: adapt the rest of the code so that it calls functions, instead of routines.

Or I'll look at the last of your scripts in the post, see if that other change works.

I already have entertainment for today. :D
wetware05
Posts: 750
Joined: 04 Dec 2020, 16:09

Re: Problems displaying an image in Gdip.

26 May 2023, 05:15

It didn't take me much effort.

I removed the init: routine and put its code at the beginning.

Result and working script (I have worked with the original version of @tuzi, at viewtopic.php?t=90001). I have opted for the version that adds the border on the outside of the image (The border is semi-transparent, i'm going to pay attention to that detail).

@Hellbent, why do your images look semi-transparent in your examples? How is that effect achieved? Any more lines to add to the potion?

Code: Select all

; Mouse over to the file to preview the content without clicking. Support ahk,txt,ini,jpg,jpeg,png,bmp,tif format.
; You must enable "show file ext name" in explorer.
; 鼠标移动到文件上面,不用点击即可预览内容。支持 ahk,txt,ini,jpg,jpeg,png,bmp,tif 格式。
; 需要在 资源管理器-显示 中勾选 “文件扩展名” 选项。

SetBatchLines, -1
CoordMode, Mouse, Screen
maxStr:=200, maxW:=500, maxH:=500

SetTimer, preview, 50

; close system file info tip.
	RegRead, ShowInfoTip, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip
	RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, 0
	pToken := Gdip_Startup()
	OnExit, GdipExit
	PreviewWindow := CreatePreviewWindow( MaxWidth := 500 , MaxHeight := 500 )
return

CreatePreviewWindow( Width , Height ){
	local Obj := {}
	Gui, New, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
	Obj.Hwnd := hPreview
	Gui, Show, NA
	Obj.Width := Width
	Obj.Height := Height
	Obj.hbm  := CreateDIBSection( Obj.Width , Obj.Height )
	Obj.hdc  := CreateCompatibleDC()
	Obj.obm  := SelectObject( Obj.hdc , Obj.hbm )
	Obj.G    := Gdip_GraphicsFromHDC( Obj.hdc )
	Gdip_SetInterpolationMode( Obj.G , 0)
	
	return obj
}
;return

preview:
 Current := GetFileUnderMouse()

  if (Displayed != Current.Path)
  {
    Displayed := Current.Path
    Ext       := Current.Ext
    if Ext in ahk,txt,ini
    {
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0) ;<<<--
      File := FileOpen(Current.Path, "r")
      btt(File.Read(maxStr),,,,"Style5")
      File.Close()
    }
    else if Ext in jpg,jpeg,png,bmp,tif
    {
      btt() ;<<--No idea what this does
      ShowPreview( Current.Path , PreviewWindow ) ;<<<<<----------
    }
    else
    {
      btt()
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)  ;<<<--
    }
  }
return

ShowPreview( Path , PreviewWindow ){
	pBitmap := Gdip_CreateBitmapFromFile( path )
	Bwidth := Gdip_GetImageWidth( pBitmap )
	Bheight := Gdip_GetImageHeight( pBitmap )
	
	Margin := 10
	MaxWidth := PreviewWindow.Width - 2 * Margin
	MaxHeight := PreviewWindow.Height - 2 * Margin

	if( BWidth > MaxWidth ){
		Width := MaxWidth
		Height := MaxWidth * ( BHeight / BWidth )
		if( Height > MaxHeight ){
			Height := MaxHeight
			Width := MaxHeight * ( BWidth / BHeight )
		}
		
	}else if( BHeight > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )

	}else{
		Width := BWidth
		Height := BHeight
	}
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( "0xFFFFFFFF" )
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , PreviewWindow.Width , PreviewWindow.Height )
	Gdip_DeleteBrush( Brush )
	Gdip_DrawImage( PreviewWindow.G , pBitmap , ( PreviewWindow.Width - width ) / 2 , ( PreviewWindow.Height - height ) / 2 , width , height )
	CoordMode, Mouse, Screen
	MouseGetPos, x, y
	UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x + 16 , y + 16 , PreviewWindow.Width , PreviewWindow.Height )
	Gdip_DisposeImage( pBitmap )
}

GdipExit:
  RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, %ShowInfoTip%
  Gdip_DisposeImage(pBitmap)
  Gdip_DeleteGraphics(G)
  SelectObject(hdc, obm)
  DeleteDC(hdc)
  DeleteObject(hbm)
	Gdip_Shutdown(pToken)
	ExitApp
return

; https://www.autohotkey.com/boards/viewtopic.php?t=51788
; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=69925
GetFileUnderMouse()
{
  static Windows:=ComObjCreate("Shell.Application").Windows

  MouseGetPos, , , hwnd, CtrlClass
  WinGetClass, WinClass, ahk_id %hwnd%

  try if (WinClass = "CabinetWClass" && CtrlClass = "DirectUIHWND3")
  {
    oAcc := Acc_ObjectFromPoint()
    Name := Acc_Parent(oAcc).accValue(0)
    NonNull(Name, oAcc.accValue(0))

    if (Name="")
      return

    for window in Windows
      if (window.hwnd = hwnd)
      {
        FolderPath := RegExReplace(window.Document.Folder.Self.Path, "(\w+?\:)\\$", "$1") ; “d:\” 转换为 “d:”

        SplitPath, Name, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := FolderPath "\" Name
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt

        return, ret
      }
  }
  else if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    oAcc := Acc_ObjectFromPoint(ChildID)
    Name := ChildID ? oAcc.accName(ChildID) : ""

    if (Name="")
      return

    SplitPath, Name, , , OutExtension, OutNameNoExt
    ret := {}
    ret.Path := A_Desktop "\" Name
    ret.Ext  := OutExtension
    ret.Name := OutNameNoExt

    return, ret
  }
}

Acc_Init() {
	Static h
	If Not h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "") {
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}

#Include <NonNull>
#Include <Gdip_All>
Addon:
Another detail. The maximum height or width variables refer to the possibility of the graphic being diagonal (it would take care of the maximum height) or vertical (it would take care of the maximum width).

Tuzi solved this by creating the ratio variable to calculate the preview version. I will work on this. (oh, you had already done it, but in a different way :salute:)

Code: Select all

ratio := Width/Height

  if (ratio>=1)
  {
    dw:=maxW
    dh:=dw/ratio
  }
  else
  {
    dh:=maxH
    dw:=ratio*dh
  }
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Problems displaying an image in Gdip.

26 May 2023, 09:25

wetware05 wrote:
26 May 2023, 05:15
@Hellbent, why do your images look semi-transparent in your examples? How is that effect achieved? Any more lines to add to the potion?
I use an editor with a white background so I needed to use another color for testing.
You can set the color and transparency by changing the line that creates the "Brush".

Code: Select all

Brush := Gdip_BrushCreateSolid( "0xFFFFFFFF" ) ;<<----- This is white ( 0xAARRGGBB [ARGB] )


Addon:
Another detail. The maximum height or width variables refer to the possibility of the graphic being diagonal (it would take care of the maximum height) or vertical (it would take care of the maximum width).

Tuzi solved this by creating the ratio variable to calculate the preview version. I will work on this. (oh, you had already done it, but in a different way :salute:)

Code: Select all

ratio := Width/Height

  if (ratio>=1)
  {
    dw:=maxW
    dh:=dw/ratio
  }
  else
  {
    dh:=maxH
    dw:=ratio*dh
  }
Your original code uses a max width and max height variable so I wrote it out so that you can use different values for both.
The code you have above is fine if both width and height are the same but it will fail if you use different values for them. The code you have also stretches images that are smaller than the "Max" size to the max size, whereas mine leaves the image at it's true size if it is smaller than the max size. If you do want it to stretch the image, then the logic needs to be adjusted a bit.
wetware05
Posts: 750
Joined: 04 Dec 2020, 16:09

Re: Problems displaying an image in Gdip.

26 May 2023, 10:18

Hi, @Hellbent ;)

I already realized why the transparency of the frame, because I read your comment to the right and deduced that AA referred to the alpha channel. But I meant if you could add semi-transparency to the image. It would be more elegant.

I'm working on the script. I added to be able to select the color of the frame, the margin, and the size of the image preview. Everything is saved in an .ini file and reads it again in a new session. I also added this routine to control that it does not overflow the screen (on a single monitor, for now):

Code: Select all

MouseGetPos, x, y ;get the current mouse position
	
	XSize:= A_ScreenWidth
	YSize:= A_ScreenHeight
	NewPos:=0

	yt:= y-PreviewWindow.Height
	If yt < 0
	{
	;StringTrimLeft, Nyt, yt, 1 ; I first tried this option, but the image was rendered on top of the mouse and was shaking, so I opted for state1 and state2.
	;y:=y-ht
	NewPos:=1
	}

	xt:= x+PreviewWindow.Width
	If xt > %XSize%
	{
	NPosX:= xt-XSize ; Look for the size that the image protrudes
	x:= x-NPosX
	}
	
	If NewPos=0
	 {
	  UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x + 16 , (y-PreviewWindow.Height) - 16 , PreviewWindow.Width , PreviewWindow.Height )
	 }
	If NewPos=1
	 {
	  UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x + 16 , y + 16 , PreviewWindow.Width , PreviewWindow.Height ) ;draw the graphics onto the window and reposition it at an offset of the cursor.
	 }
On the desktop everything is fine, but I have problems with total commander now (I don't know if what I added is what breaks it). I'm doing tests. To top it off, the positioning of the images works well in Total Commander x32, but bad in X64... very strange!
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Problems displaying an image in Gdip.

26 May 2023, 10:47

wetware05 wrote:
26 May 2023, 10:18
Hi, @Hellbent ;)

I already realized why the transparency of the frame, because I read your comment to the right and deduced that AA referred to the alpha channel. But I meant if you could add semi-transparency to the image. It would be more elegant.
You can set the transparency for the whole window by adding a alpha value ( 0-255 ) to the last optional argument of the UpdateLayeredWindow() function. It is actually how the code you have is hiding the display window when not in use.

Code: Select all

UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x + 16 , y + 16 , PreviewWindow.Width , PreviewWindow.Height ) ;<<--Default ( 255 )

UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x + 16 , y + 16 , PreviewWindow.Width , PreviewWindow.Height , Alpha := 128 ) ;<<-- 50% transparency / opacity 
wetware05
Posts: 750
Joined: 04 Dec 2020, 16:09

Re: Problems displaying an image in Gdip.

26 May 2023, 11:56

Hellbent wrote:
26 May 2023, 10:47
wetware05 wrote:
26 May 2023, 10:18
Hi, @Hellbent ;)

I already realized why the transparency of the frame, because I read your comment to the right and deduced that AA referred to the alpha channel. But I meant if you could add semi-transparency to the image. It would be more elegant.
You can set the transparency for the whole window by adding a alpha value ( 0-255 ) to the last optional argument of the UpdateLayeredWindow() function. It is actually how the code you have is hiding the display window when not in use.

Code: Select all

UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x + 16 , y + 16 , PreviewWindow.Width , PreviewWindow.Height ) ;<<--Default ( 255 )

UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x + 16 , y + 16 , PreviewWindow.Width , PreviewWindow.Height , Alpha := 128 ) ;<<-- 50% transparency / opacity 
I thought it would be more complicated! It works, thank you very much. :thumbup:
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Problems displaying an image in Gdip.

26 May 2023, 12:23

wetware05 wrote:
26 May 2023, 11:56
Everything is saved in an .ini file and reads it again in a new session.

Depending on what you are doing. It is possible to save your values directly to your script. There are a few limitations ( you can't do this with a compiled script for example ).
If you just have a few simple values that you want to save for the next time you run the script you can add a ini section to your code.

Simple example.

Code: Select all


/*


[ SavedData ]
CurrentIndex=0


*/

#SingleInstance, Force

iniRead, value , % A_ScriptFullPath , SavedData , CurrentIndex

++value

iniwrite, % value , % A_ScriptFullPath , SavedData , CurrentIndex

MsgBox, % "You have ran this script " value " times."

reload

return

*ESC::ExitApp

wetware05
Posts: 750
Joined: 04 Dec 2020, 16:09

Re: Problems displaying an image in Gdip.

26 May 2023, 12:34

Hellbent wrote:
26 May 2023, 12:23
wetware05 wrote:
26 May 2023, 11:56
Everything is saved in an .ini file and reads it again in a new session.

Depending on what you are doing. It is possible to save your values directly to your script. There are a few limitations ( you can't do this with a compiled script for example ).
If you just have a few simple values that you want to save for the next time you run the script you can add a ini section to your code.

Simple example.

Code: Select all


/*


[ SavedData ]
CurrentIndex=0


*/

#SingleInstance, Force

iniRead, value , % A_ScriptFullPath , SavedData , CurrentIndex

++value

iniwrite, % value , % A_ScriptFullPath , SavedData , CurrentIndex

MsgBox, % "You have ran this script " value " times."

reload

return

*ESC::ExitApp

Yes thanks, I had already implemented it like this:

The thing about the if !MaxWidth etc. conditional is to make sure they always have a value. Maybe something for newbies. I do it while I'm working on the code, in case something goes wrong. The first routine is for when a person uses it for the first time.

Code: Select all

f !FileExist("NewConfig.ini")
  {
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxWidth
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxHeight
  IniWrite, 16, NewConfig.ini, Preview_TCM, Margin
  IniWrite, 0x99FFFF00, NewConfig.ini, Preview_TCM, SetColor
  ;IniWrite, Window7, NewConfig.ini, Preview_TCM, NoW
  }

If !MaxWidth
 {
  IniRead, MaxWidth, NewConfig.ini, Preview_TCM, MaxWidth
 }
If !MaxHeight
 {
  IniRead, MaxHeight, NewConfig.ini, Preview_TCM, MaxHeight
 }
 If !Margin
 {
  IniRead, Margin, NewConfig.ini, Preview_TCM, Margin
 }
If !SetColor
 {
  IniRead, SetColor, NewConfig.ini, Preview_TCM, SetColor
 }
wetware05
Posts: 750
Joined: 04 Dec 2020, 16:09

Re: Problems displaying an image in Gdip.

26 May 2023, 13:21

wetware05 wrote:
26 May 2023, 10:18
Hi, @Hellbent ;)

I already realized why the transparency of the frame, because I read your comment to the right and deduced that AA referred to the alpha channel. But I meant if you could add semi-transparency to the image. It would be more elegant.

I'm working on the script. I added to be able to select the color of the frame, the margin, and the size of the image preview. Everything is saved in an .ini file and reads it again in a new session. I also added this routine to control that it does not overflow the screen (on a single monitor, for now):

Code: Select all

MouseGetPos, x, y ;get the current mouse position
	
	XSize:= A_ScreenWidth
	YSize:= A_ScreenHeight
	NewPos:=0

	yt:= y-PreviewWindow.Height
	If yt < 0
	{
	;StringTrimLeft, Nyt, yt, 1 ; I first tried this option, but the image was rendered on top of the mouse and was shaking, so I opted for state1 and state2.
	;y:=y-ht
	NewPos:=1
	}

	xt:= x+PreviewWindow.Width
	If xt > %XSize%
	{
	NPosX:= xt-XSize ; Look for the size that the image protrudes
	x:= x-NPosX
	}
	
	If NewPos=0
	 {
	  UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x + 16 , (y-PreviewWindow.Height) - 16 , PreviewWindow.Width , PreviewWindow.Height )
	 }
	If NewPos=1
	 {
	  UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x + 16 , y + 16 , PreviewWindow.Width , PreviewWindow.Height ) ;draw the graphics onto the window and reposition it at an offset of the cursor.
	 }
On the desktop everything is fine, but I have problems with total commander now (I don't know if what I added is what breaks it). I'm doing tests. To top it off, the positioning of the images works well in Total Commander x32, but bad in X64... very strange!
This routine that prevents the image from leaving the monitor does not work well. It works on the desktop, but it's not a explorer window (non-maximized), or in Total commander.

Any idea what could be the problem? In Explorer or Total Commander the images are displayed quite displaced from the origin (vertically). It must have something to do with CoordMode, Mouse, Screen, as the script seems to interpret the coordinates with respect to the window, ignoring that it has been asked to stick to the screen.


I'll share what I have so far in a bit.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Giresharu, Google [Bot] and 109 guests