Resize Picture and Keep Aspect Ratio in Autohotkey GUI - autohotkey

Is it possible to have an image be 100% of the window width and keep it's aspect ratio while resizing an AutoHotKey GUI?
I have a simple GUI as follows:
Gui +Resize
Gui, Add, Picture, w440 h-1 vProductImage, default.png
Gui, Show, , MyApp
The closest thing I have been able to come to is Anchor.ahk http://www.autohotkey.com/board/topic/4105-control-anchoring-v4-for-resizing-windows/
Using it, I can have the image resized when the window is resized but it doesn't keep it's aspect ratio and gets deformed
Does anyone know how I can do this?

Closest thing I could come up with:
Assuming the picture is 440x350, is 85 pixels from the top of the app window (left:0)
GuiSize:
if(A_GuiWidth < A_GuiHeight)
{
GuiControl, MoveDraw, ProductImage, % "w" . (A_GuiWidth - 20) . " h" . (350/440) * (A_GuiWidth - 20)
}
else
{
GuiControl, MoveDraw, ProductImage, % "w" . (440/350) * (A_GuiHeight - 85) . " h" . (A_GuiHeight - 85)
}
return
(the 20 is for window padding)

Related

Finding a pixel and tracking its color change

There is a script that for some reason does not work.
I explain the situation: There is a mini game in which there are green rings and they change their position (not random) every time the white ring stops using the space bar on them.
I wrote a little script to find the green color, but for some reason it does not work.
F5::
loop {
PixelGetColor, color1, 957, 672, RGB
PixelGetColor, color2, 957, 672, RGB
if(color1 != 0x10A04B){
Sleep, 80
} else {
Soundbeep
Sleep, 80
}
if(color2 != 0xFDFFFE){
Sleep, 80
} else {
Send, {space}
}
}
return
To help you fully understand the mini game, I'm sending you a link to the video: https://youtu.be/b4y1aiQNea4
Please help me understand the implementation. Thank you!
Use a timer instead of the loop
Try using Alt or Slow mode
For finding the green ring coordinates try using PixelSearch, then you will be able to specify variation of the color (it's necessary due to it being partially transparent)
colorchange(x,y){
PixelGetColor,color,x,y
if (color=0xffffffffff){
Return 1}Else{
Return 0}
}
if colorchange(X,Y){
Send,{Space}
}

Ghostscript -- convert PS to PNG, rotate, and scale

I have an application that creates very nice data plots rendered in PostScript with letter size and landscape mode. An example of the input file is at http://febo.com/uploads/blip.ps. [ Note: this image renders properly in a viewer, but the PNG conversion comes out with the image sideways. ] I need to convert these PostScript files into PNG images that are scaled down and rotated 90 degrees for web presentation.
I want to do this with ghostscript and no other external tool, because the conversion program will be used on both Windows and Linux systems and gs seems to be a common denominator. (I'm creating a perl script with a "PS2png" function that will call gs, but I don't think that's relevant to the question.)
I've searched the web and spent a couple of days trying to modify examples I've found, but nothing I have tried does the combination of (a) rotate, (b) resize, (c) maintain the aspect ratio and (d) avoid clipping.
I did find an example that injects a "scale" command into the postscript stream, and that seems to work well to scale the image to the desired size while maintaining the aspect ratio. But I can't find a way to rotate the resized image so that the, e.g., 601 x 792 point (2504 x 3300 pixel) postscript input becomes an 800 x 608 pixel png output.
I'm looking for the ghostscript/postscript fu that I can pass to the gs command line to accomplish this.
I've tried gs command lines with various combinations of -dFIXEDMEDIA, -dFitPage, -dAutoRotatePages=/None, or /All, -c "<> setpagedevice", changing -dDISPLAYWIDTHPOINTS and -dDISPLAYHEIGHTPOINTS, -g[width]x[height], -dUseCropBox with rotated coordinates, and other things I've forgotten. None of those worked, though it wouldn't surprise me if there's a magic combination of some of them that will. I just haven't been able to find it.
Here is the core code that produces the scaled but not rotated output:
## "$molps" is the input ps file read to a variable
## insert the PS "scale" command
$molps = $sf . " " . $sf . " scale\n" . $molps;
$gsopt1 = " -r300 -dGraphicsAlphaBits=4 -dTextAlphaBits=4";
$gsopt1 = $gsopt1 . " -dDEVICEWIDTHPOINTS=$device_width_points";
$gsopt1 = $gsopt1 . " -dDEVICEHEIGHTPOINTS=$device_height_points";
$gsopt1 = $gsopt1 . " -sOutputFile=" . $outfile;
$gscmd = "gs -q -sDEVICE=pnggray -dNOPAUSE -dBATCH " . $gsopt1 . " - ";
system("echo \"$molps\" \| $gscmd");
$device_width_points and $device_height_points are calculated by taking the original image size and applying the scaling factor $sf.
I'll be grateful to anyone who can show me the way to accomplish this. Thanks!
Better Answer:
You almost had it with your initial research. Just set orientation in the gs call:
... | gs ... -dAutoRotatePages=/None -c '<</Orientation 3>> setpagedevice' ...
cf. discussion of setpagedevice in the Red Book, and ghostscript docs (just before section 6.2)
Original Answer:
As well as "scale", you need "rotate" and "translate", not necessarily in that order.
Presumably these are single-page PostScript files?
If you know the bounding box of the Postscript, and the dimensions of the png, it is not too arduous to calculate the necessary transformation. It'll be about one line of code. You just need to ensure you inject it in the correct place.
Chapter 6 of the Blue Book has lots of details
A ubc.ca paper provides some illustrated examples (skip to page 4)
Simple PostScript file to play around with. You'll just need the three translate,scale,rotate commands in some order. The rest is for demonstrating what's going on.
%!
% function to define a 400x400 box outline, origin at 0,0 (bottom left)
/box { 0 0 moveto 0 400 lineto 400 400 lineto 400 0 lineto closepath } def
box clip % pretend the box is our bounding box
clippath stroke % draw initial black bounding box
(Helvetica) findfont 50 scalefont setfont % setup a font
% draw box, and show some text # 100,100
box stroke
100 100 moveto (original) show
% try out some transforms
1 0 0 setrgbcolor % red
.5 .5 scale
box stroke
100 100 moveto (+scaled) show
0 1 0 setrgbcolor % green
300 100 translate
box stroke
100 100 moveto (+translated) show
0 0 1 setrgbcolor % blue
45 rotate
box stroke
100 100 moveto (+rotated) show
showpage
It may be possible to insert the calculated transformation into the gs commandline like this:
... | gs ... -c '1 2 scale 3 4 translate 5 6 rotate' -# ...
Thanks to JHNC, I think I have it licked now, and for the benefit of posterity, here's what worked. (Please upvote JHNC, not this answer.)
## code to determine original size, scaling factor, rotation goes above
my $device_width_points;
my $device_height_points;
my $orientation;
if ($rotation) {
$orientation = 3;
$device_width_points = $ytotal_png_pt;
$device_height_points = $xtotal_png_pt;
} else {
$orientation = 0;
$device_width_points = $xtotal_png_pt;
$device_height_points = $ytotal_png_pt;
}
my $orientation_string =
" -dAutoRotatePages=/None -c '<</Orientation " .
$orientation . ">> setpagedevice'";
## $ps = .ps file read into variable
## insert the PS "scale" command
$ps = $sf . " " . $sf . " scale\n" . $ps;
$gsopt1 = " -r300 -dGraphicsAlphaBits=4 -dTextAlphaBits=4";
$gsopt1 = $gsopt1 . " -dDEVICEWIDTHPOINTS=$device_width_points";
$gsopt1 = $gsopt1 . " -dDEVICEHEIGHTPOINTS=$device_height_points";
$gsopt1 = $gsopt1 . " -sOutputFile=" . $outfile;
$gsopt1 = $gsopt1 . $orientation_string;
$gscmd = "gs -q -sDEVICE=pnggray -dNOPAUSE -dBATCH " . $gsopt1 . " - ";
system("echo \"$ps\" \| $gscmd");
One of the problems I had was that some options apparently don't play well together -- for example, I tried using the -g option to set the output size in pixels, but in that case the rotation didn't work. Using the DEVICE...POINTS commands instead did work.

Dynamic expanding visual basic forms

I have what is most likely a simple question. I have a visual basic form but when I expand it none of the fields or text expands with the window. I was wondering how to make it so the form dynamically expands when someone maximizes or expands the window on the desktop Could someone please advise thank you!
Each control has the properties VerticleAnchor and HorizontalAnchor.
These can be left right or both (top or bottom for verticle) and if it is left and top (default) they stay those distances from the top and left sides. Changing them to right and bottom keep their distances from the right and bottom. Both resizes the control to have the same spacing from both as the form resizes.
Also double chack that the CanGrow and CanShrink are true to allow for them to resize with the form.
Hope that helps!
Edit:
Here is some code from my predecessor that does it using the event:
Private Sub Form_Resize()
On Error GoTo Err_Form_Resize
If CurrentProject.AllForms("frmFMEA_PartA").IsLoaded Then
Dim DatasheetW As Double
Dim DatasheetH As Double
Dim FormW As Double
Dim FormH As Double
DatasheetW = Me.frmFMEA_PartB_Subform.width
FormW = Me.WindowWidth
DatasheetH = Me.frmFMEA_PartB_Subform.Height
FormH = Me.WindowHeight
'MsgBox FormH
'MsgBox DatasheetH
Me.frmFMEA_PartB_Subform.width = IIf(FormW - 360 > 0, FormW - 360, 1) '390
Me.frmFMEA_PartB_Subform.Height = IIf(FormH - 3405 > 0, FormH - 3405, 1) '3195
Me.text.Left = IIf(FormW - 2340 > 0, FormW - 2340, 1)
Me.text_Logo.Left = IIf(FormW - 2340 > 0, FormW - 2340, 1)
End If
Exit_Form_Resize:
Exit Sub
Err_Form_Resize:
MsgBox Err.Description
Resume Exit_Form_Resize
End Sub
as you can see its a lot of math, trial, and error so I try to do it using the form level properties but maybe this will spart some ideas.

change the coordmode from the active window to any window

this is the situation:
1) I have 3 Windows;
2) My mouse is positioned over any of them (active table under the mouse cursor);
3) I have the ahk_id of both Windows (stored in global variables);
4) Every 5 seconds, I would check (regardless of the movement of the mouse cursor), if a pixel of a specific window (window1, window2...) has a certain color;
5) Click with a controlclik of that pixel and regain control of the starting window under the mouse cursor.
checktime(){
var := Mod(A_Sec, 5)
if (var = 0){
checkpixel(window1) ; window1 is an ahk_id, stored in a global variable
checkpixel(window2)
checkpixel(window3)
}
checkpixel(window){
CoordMode, ToolTip, window ; this line of code is definitely wrong, what do you recommend?
pixelgetcolor, color, 440, 295
if(color=0x4E3500){
controlclick, x440 y295, ahk_id %window%
}
thanks in advance for the answers!

Steam Utility Menu Autohotkey

I have looked thoroughly around the interwebs for this, but I was wondering if anyone had a way that I could remap Shift + Tab so that it brings up a context menu like you see in steam. This would have a transparent background, and no window icon. And just like the steam menu, I want it to have stuff that would be useful. I have tried to do this on my own, but I was not successful. Anyone have any ideas?
I feel like this is much more complicated than you make it out to be.
Here is some code to get the fade effect without a window icon. Use Shift+Tab.
#SingleInstance force
#NoTrayIcon
SetBatchLines, -1
SysGet, VirtualWidth, 78
SysGet, VirtualHeight, 79
Transparency := 0
Fade := 0
Settimer, GUI2AlwaysOnTop, 10 ; Keep gui 2 on top
Gui, 1: Default
Gui, Color, 0x000000 ; Color to black
Gui, +LastFound +AlwaysOnTop -Caption +E0x20 ; Click through GUI always on top.
Gui, 1: +owner
WinSet, Transparent, %Transparency%
Gui, Show, x0 y0 w%VirtualWidth% h%VirtualHeight% ; Cover entire screen, may have to adjust X if you have multiple monitors
Return
Shift & Tab::
If (Fade:=!Fade)
FadeIn(500, 40)
Else
FadeOut(500)
Return
FadeIn(TotalTime = 500, TransFinal = 255)
{
StartTime := A_TickCount
Loop
{
Transparency := Round(((A_TickCount-StartTime)/TotalTime)*TransFinal)
WinSet, Transparent, %Transparency%, ahk_class AutoHotkeyGUI
if (Transparency >= TransFinal)
break
Sleep, 10
}
}
FadeOut(TotalTime = 500)
{
StartTime := A_TickCount
Loop
{
Transparency := ((TimeElapsed := A_TickCount-StartTime) < TotalTime) ? 100*(1-(TimeElapsed/TotalTime)) : 0
WinSet, Transparent, %Transparency%, ahk_class AutoHotkeyGUI
if (Transparency = 0)
break
Sleep, 10
}
}
GUI2AlwaysOnTop:
Gui, 2: +AlwaysonTop
return
A good amount of the GUI code is from SmartBright. I've had these fade functions around, I know I modified someone else's script to my liking, but I cannot find the source.