Using variable in a script sub

Please check the FAQ (https://www.xyplorer.com/faq.php) before posting a question...
Post Reply
klownboy
Posts: 4463
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.8737 at 100% 2560x1440

Using variable in a script sub

Post by klownboy »

Hi, I've been going nuts trying to do something very simple in a script. I have a working script which I've assigned a TB button. It basically just provides a menu to crop a photo down to specific resolutions mainly just to view the photos as wallpaper on a few computers which have different aspect ratios (eg., one computer is 8x5 (1920x1200) and anther is 16x9 (1920x1080). The original photos have different resolutions and aspect ratios (3x2, 4x3, and 16x9). I'd like to make the script (and me :) ) a bit smarter such that it detects the "property dimensions" of the current file selected (e.g 4320x3240) and based on that, the script goes to a "sub" section ot the script which performs the appropriate actions using Irfanview to crop the photo to the desired resolution. At this point, I'll probably just work with one file (jpg) at a time. I figured I can use the property command to determine the jpg file resoltion, but I want the script to go to a particular section of the script based on that resolution. This portion of the code will give you an idea of what I'm trying to accomplish.

Code: Select all

//"IrfanView Convert to 16x9|D:\Graphics\Icons\k321-icon-218.ico";
 $d = property(dimensions, <curitem>);
 sub "res_$d";

//"Convert Landscape 4320x3240 to 16x9|D:\Graphics\Icons\k321-icon-218.ico";
"res_$d : _res$d";
$a = input("Crop offset "y" value from 0,0",Enter number from 1 to 810 (405 centers crop vetically). ,405, "m",,300,300);
   run """D:\Graphics\IrfanView\i_view32.exe"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,4320,2430) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;

//"Convert Landscape 3888x2592 to 16x9|D:\Graphics\Icons\program-small-icons.ico;
"res_$d : res_$d";
$a = input("Crop offset "y" value from 0,0","Enter number from 1 to 405 (203 is centered)." ,203, "m",,300,300);
   run """D:\Graphics\IrfanView\i_view32.exe"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,3888,2187) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;

"res_$d : res_$d";
//"Convert Portrait 3240x4320 to 16x9|D:\Graphics\Icons\k321-icon-219.ico";
$a = input("Crop offset "y" value from 0,0","Enter number from 1 to 2498 (1248 is centered)." ,1248, "m",,300,300);
   run """D:\Graphics\IrfanView\i_view32.exe"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,3240,1822) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;
Obviously, I must be messing up the variable syntax somehow, but I tried numerous variations without any luck. Note: The Irfanview and Input command work fine. How do I get the script to go to the appropriate section of the script based on the property dimension (resolution). I'm not sure if having the labels the same, but based on the "property dimension" variable will be a problem either since I've been testing this with only one label at this point and still can't get it to function (Error: The list of Labels did not match any script...) Any help would be greatly appreciated.
Thanks,
Ken

highend
Posts: 14956
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Using variable in a script sub

Post by highend »

Afaik (but I can be wrong), variables in subs aren't supported. I tried something different a few months ago and wasn't able to get it working. But, if it's not possible I really like to see that this gets added.

Don?
One of my scripts helped you out? Please donate via Paypal

klownboy
Posts: 4463
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.8737 at 100% 2560x1440

Re: Using variable in a script sub

Post by klownboy »

Thanks highend for responding. Yes, that its too bad variables are not supported in subs. I can think of quite a few uses.
What would you suggest as a work around in my particular situation (I'm still new to scripting)? Do I have to use the if/else/elseif structure commands? For the above, would that be something like:

Code: Select all

If  ($d == 4320 x 3240) {
sub "_4320 x 3240"
}
elseif ($d == 3888 x 2592) {
sub "_3888 x 2592"
}
Or, I suppose if I have to go this way I could just put the above "Input" and" Irfanview" commands at that spot where the sub "_4320 x 3240" is and continue with elseif commands? Not sure what the best way to proceed is.
Thanks,
Ken

highend
Posts: 14956
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Using variable in a script sub

Post by highend »

Code: Select all

Do I have to use the if/else/elseif structure commands?
Probably the only option atm.
One of my scripts helped you out? Please donate via Paypal

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: Using variable in a script sub

Post by Stefan »

 


Did you mean something like this?

Code: Select all

"Main"
  $res = "4320 x 3240 OR 3888 x 2592 OR 1024 x 768";
  $d = input(Test,"go to sub: $res", "$res");
  sub "_res_$d";

"_res_1024 x 768"
  msg "This is just _res_1024 x 768. Please update ;-)";

"_res_3888 x 2592"
  msg "You are in sub _res_3888 x 2592 now, welcome !!!";

"_res_4320 x 3240"
  msg "Did you entered _res_4320 x 3240 ????";




The same with more ideas:

Code: Select all

"Main"
  //Make an variable global to all sub-scripts:
  global $res;

  //Resolutions list:
  //(Also handy to check UserInput against available SUBs)
  $res = "4320 x 3240 OR 3888 x 2592 OR 1024 x 768";

  //Prompt user to select one resolution:
  $d = input(Test,"go to sub: $res", "$res");
  //If just OK'ed without any chose, end:
  end($d==$res), "Please select ONE of the evailable resolutions. Script quits!";

  //If the entered string is in the list of available resolutions, go to sub:
  if(strpos($res,$d) != -1){
      sub "_res_$d";
  }else{
      msg "Res not supported.";
  }



// === The Subs / Functions ===  //
"_res_1024 x 768"
  global $res;
  msg "This is just _res_1024 x 768. Please update!";
  msg "Available resolutions are: $res ('global' was used)";


"_res_3888 x 2592"
  //here, the global command is missed!!!
  msg "You are in sub _res_3888 x 2592 now, welcome!";
  msg "Available resolutions are: $res  ('global' was NOT used)";


"_res_4320 x 3240"
  msg "Did you entered _res_4320 x 3240?";
  msg "User chose: $d  ('global' was NOT used)";

PeterH
Posts: 2829
Joined: 21 Nov 2005 20:39
Location: DE W11Pro 24H2, 1920*1200*100% 3840*2160*150%

Re: Using variable in a script sub

Post by PeterH »

Basically I think Stefan is right.

But I would never use the content of an (externally filled) variable as a label for a subroutine call. (You would have to code a routine for every possible value the variable might have...)

So I'd use If/Elseif/... to ask for defined values and call the associated subs - and have errorhandling for non-expected values in a terminating Else part.

RalphM
Posts: 2091
Joined: 27 Jan 2005 23:38
Location: Cairns, Australia

Re: Using variable in a script sub

Post by RalphM »

PeterH wrote:Basically I think Stefan is right.

But I would never use the content of an (externally filled) variable as a label for a subroutine call. (You would have to code a routine for every possible value the variable might have...)

So I'd use If/Elseif/... to ask for defined values and call the associated subs - and have errorhandling for non-expected values in a terminating Else part.
Or use the variables from the properties to calculate the aspect ratio and call your subs depending on this.
Ralph :)
(OS: W11 25H2 Home x64 - XY: Current x64 beta - Office 2024 64-bit - Display: 1920x1080 @ 125%)

klownboy
Posts: 4463
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.8737 at 100% 2560x1440

Re: Using variable in a script sub

Post by klownboy »

Thanks highend, Stefan, PeterH, and RalphM for all your input. As I mentioned earlier I had a working script where I had to select the photo size, but I wanted to automate the process at least somewhat so I did obtain the property dimension variable and based on that used if/elseif/else structure commands to perform the cropping actions in Irfanview.

Code: Select all

"IrfanView Photo Crop to 16x9|D:\Graphics\Icons\k321-icon-218.ico";
      $d = property(dimensions, <curitem>);
      $g_IrfanPath="d:\graphics\irfanView\i_view32.exe";
  if ($d == "4320 x 3240") {
      run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,4320,2430) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;
      end
      }
  elseif ($d == "3888 x 2592") {
      run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,3888,2187) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;
      end
      }
  elseif ($d == 3240 x 4320) {
      run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,3240,1822) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;
      end
      }
  elseif ($d == 2592 x 3888) { 
        run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,2592,1458) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;
        end
        }
  elseif ($d == 2432 x 4320) {
       run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,2432,1368) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;
       end
       }
  Else {
       end
       }
"-"
"IrfanView Photo Crop to 8x5|D:\Graphics\Icons\k321-icon-219.ico";
     $g_IrfanPath="d:\graphics\irfanView\i_view32.exe";
     $d = property(dimensions, <curitem>); 
  if ($d == "4320 x 3240") {
     run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,4320,2700) /convert=<curpath>\<curbase>_8x5.<curext>", , 2,0;
     end
     }
  elseif ($d == "3888 x 2592") {
     run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,3888,2430) /convert=<curpath>\<curbase>_8x5.<curext>", , 2,0;
     end
     }
bla, bla, bla...converting the same size photos to an 8x5 (1920x1200) vs 16x9 (1920x1080)...
I'm not sure yet about how to handle error control or if I'm doing the end statements in the right place or if they are even needed as much as I'm using them especially in the "else" statement. Any suggestions are VERY welcome. I probably don't need the /resample command line argument or even the /aspectratio or /jpgq=100 in Irfanview when Cropping. I think /resample is only necessary for "/resize" according to the help.
Thanks,
Ken

highend
Posts: 14956
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Using variable in a script sub

Post by highend »

I would it do it in this way:

Code: Select all

"IrfanView Photo Crop to 16x9|D:\Graphics\Icons\k321-icon-218.ico";
  global $curWidth, $newHeight;
  $d = property(dimensions, <curitem>);
  $curWidth = gettoken($d, 1, " x ");

  if ($d == "4320 x 3240") {
    $newHeight = "2430"; sub "_ExecuteIV";
  }
  elseif ($d == "3888 x 2592") {
      $newHeight = "2187"; sub "_ExecuteIV";
  }
  elseif ($d == "3240 x 4320") {
      $newHeight = "1822"; sub "_ExecuteIV";
  }
  elseif ($d == "2592 x 3888") {
      $newHeight = "1458"; sub "_ExecuteIV";
  }
  elseif ($d == "2432 x 4320") {
      $newHeight = "1368"; sub "_ExecuteIV";
  }
  Else {
    msg "Unknown dimensions, please add another elseif for ". $d . " px!";
  }

"_ExecuteIV"
  global $curWidth, $newHeight;
  $g_IrfanPath="d:\graphics\irfanView\i_view32.exe";
  run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,$curWidth,$newHeight) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;
You don't need end statements in your elseif clauses.
One of my scripts helped you out? Please donate via Paypal

klownboy
Posts: 4463
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.8737 at 100% 2560x1440

Re: Using variable in a script sub

Post by klownboy »

Hi again highend, I messed up big time on my last post. When I deleted out some old comments on each if and else line, I also unintentionally deleted out the "input" line code (you were probably wondering where the "$a" came from). The following is what I should have posted. I like what you sent, but at the same time, I do want to have the flexibility of adjusting the crop vertically. I actually find myself adjusting the crop from simply centered quite a bit.

Code: Select all

"IrfanView Photo Crop to 16x9|D:\Graphics\Icons\k321-icon-218.ico";
      $d = property(dimensions, <curitem>);
      $g_IrfanPath="d:\graphics\irfanView\i_view32.exe";
  if ($d == "4320 x 3240") {
      $a = input("Crop offset y value from 0,0","Enter number from 1 to 810 (405 centers crop vetically)." ,405, "m",,300,250);
      run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,4320,2430) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;
      end
      }
  elseif ($d == "3888 x 2592") {
      $a = input("Crop offset y value from 0,0","Enter number from 1 to 405 (203 centers crop)." ,203, "m",,300,250);
      run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,3888,2187) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;
      end
      }
  elseif ($d == 3240 x 4320) {
      $a = input("Crop offset y value from 0,0","Enter number from 1 to 2498 (1248 centers crop)." ,1248, "m",,300,250);
      run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,3240,1822) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;
      end
      }
  elseif ($d == 2592 x 3888) { 
        $a = input("Crop offset "y" value from 0,0","Enter number from 1 to 2430 (1215 is centered)." ,1215, "m",,300,250);
        run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,2592,1458) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;
        end
        }
  elseif ($d == 2432 x 4320) {
       $a = input("Crop offset "y" value from 0,0","Enter number from 1 to 2952 (1476 centers crop)." ,1476, "m",,300,250);
       run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,2432,1368) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;
       end
       }
       Else {
       end
       }
       
"-"

"IrfanView Photo Crop to 8x5|D:\Graphics\Icons\k321-icon-219.ico";
     $g_IrfanPath="d:\graphics\irfanView\i_view32.exe";
     $d = property(dimensions, <curitem>);
     
  if ($d == "4320 x 3240") {
     $a = input("Crop offset y value from 0,0","Enter number from 1 to 540 (270 centers crop vertically)." ,270, "m",,300,250);
     run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,4320,2700) /convert=<curpath>\<curbase>_8x5.<curext>", , 2,0;
     end
     }
  elseif ($d == "3888 x 2592") {
     $a = input("Crop offset y value from 0,0",Enter number from 1 to 162 (81 centers crop vertically)." ,81, "m",,300,250);
     run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,3888,2430) /convert=<curpath>\<curbase>_8x5.<curext>", , 2,0;
     end
     }
bla, bla, bla...converting the same size photos to an 8x5 (1920x1200) vs 16x9 (1920x1080)...
Hopefully, I can work in your ideas and code with the input flexibility.
Thanks, and sorry I messed up in the last post,
Ken

highend
Posts: 14956
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Using variable in a script sub

Post by highend »

Code: Select all

"IrfanView Photo Crop to 16x9|D:\Graphics\Icons\k321-icon-218.ico";
  global $a, $curWidth, $newHeight;
  $d = property(dimensions, <curitem>);
  $curWidth = gettoken($d, 1, " x ");

  if ($d == "4320 x 3240") {
    $a = input("Crop offset y value from 0,0","Enter number from 1 to 810 (405 centers crop vetically)." , 405, "m", ,300,250);
    $newHeight = "2430"; sub "_ExecuteIV";
  }
  elseif ($d == "3888 x 2592") {
    $a = input("Crop offset y value from 0,0","Enter number from 1 to 405 (203 centers crop)." , 203, "m", ,300,250);
    $newHeight = "2187"; sub "_ExecuteIV";
  }
  elseif ($d == "3240 x 4320") {
    $a = input("Crop offset y value from 0,0","Enter number from 1 to 2498 (1248 centers crop)." , 1248, "m", ,300,250);
    $newHeight = "1822"; sub "_ExecuteIV";
  }
  elseif ($d == "2592 x 3888") {
    $a = input("Crop offset "y" value from 0,0","Enter number from 1 to 2430 (1215 is centered)." , 1215, "m", ,300,250);
    $newHeight = "1458"; sub "_ExecuteIV";
  }
  elseif ($d == "2432 x 4320") {
    $newHeight = "1368"; sub "_ExecuteIV";
  }
  else {
    $a = input("Crop offset "y" value from 0,0","Enter number from 1 to 2952 (1476 centers crop)." , 1476, "m", ,300,250);
    msg "Unknown dimensions, please add another elseif for ". $d . " px!";
  }

"_ExecuteIV"
  global $a, $curWidth, $newHeight;
  $g_IrfanPath="d:\graphics\irfanView\i_view32.exe";
  run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,$curWidth,$newHeight) /convert=<curpath>\<curbase>_16x9.<curext>", , 2,0;
One of my scripts helped you out? Please donate via Paypal

klownboy
Posts: 4463
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.8737 at 100% 2560x1440

Re: Using variable in a script sub

Post by klownboy »

Thanks highend for all your input. It's nice to be able to utilize the "sub" command such that the "run" is not repeated a million times. I did have to make an additional tweak because the script performs similar operations (with another menu heading) to crop photos not only to 16x9 (for a 1920x1080 monitor) but also 8x5 (for a 1920x1200 monitor). The new filenames for the cropped photos added "_16x9" to the name and I wanted "_8x5" added to the name of those photos cropped to 8x5. I know I could do this with 2 different subs for the "_16x9" and"_8x5", but obviously I wanted to keep it to one sub if possible. So I added the following:

Code: Select all

"IrfanView Photo Crop to 16x9|D:\Graphics\Icons\k321-icon-218.ico";
  global $a, $xy, $curWidth, $newHeight;
  $xy = "16x9";
bla, bla bla...

"IrfanView Photo Crop to 8x5|D:\Graphics\Icons\k321-icon-219.ico";
     global $a,$xy, $curWidth, $newHeight;
     $xy = "8x5";
bla, bla, bla...

"_ExecuteIV"
  global $a, $xy, $curWidth, $newHeight;
  $g_IrfanPath="d:\graphics\irfanView\i_view32.exe";
  run """$g_IrfanPath"" ""<curitem>"" /aspectratio /jpgq=100 /resample /crop=(0,$a,$curWidth,$newHeight) /convert=<curpath>\<curbase>_$xy.<curext>", , 2,0;
By the way, I assumed I would have to repeat much of the variable information since there are multiple headers in the menu (i.e., I don't believe XY would set the variable info made under one heading in the menu (e.g., 16x9) if you clicked the 8x5 menu header...if that makes sense.
Also, I noticed that many times after a successfull operation (cropping and file save), I would get a damaged file on the thumbnail itself as shown in this clip.
XY_bad_image.JPG
The file is fine however and the thumbnail ends up being fine as well after I refresh the thumbnails but that's a bit time consuming. Should I or can I do something like a wait or sleep in the script or possibly change the run "show" or "wait" options instead of hiding them?

Maybe this issue is for Don or maybe it's not really an issue, I noticed if a file is totally deleted the thumbnail is still in tack such that if you re-create the file with the same name (jpg, in my case with a completely different crop) the old thumbnail is still there (with the old photo crop). It's not until you refresh the entire folder do you see the new thumbnail as it should be. Another, by the way, is there any way to refresh the thumbnail for a single file?
Thanks again for all your help...it's helping me to learn along with frequent visits to the help file,
Ken
To see the attached files, you need to log into the forum.

admin
Site Admin
Posts: 66381
Joined: 22 May 2004 16:48
Location: Win8.1, Win10, Win11, all @100%
Contact:

Re: Using variable in a script sub

Post by admin »

klownboy wrote:is there any way to refresh the thumbnail for a single file?
Yep, right click the Views or Toggle Thumbnails button on the toolbar to get the commands.

highend
Posts: 14956
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Using variable in a script sub

Post by highend »

Should I or can I do something like a wait or sleep in the script or possibly change the run "show" or "wait" options instead of hiding them?
Why don't you just try it? I don't know why the files get damaged but I don't think it's a XYplorer's scripting issue.

wait(<time in miliseconds>)

is the command that you can use (apart from the wait option for the "run" command).
One of my scripts helped you out? Please donate via Paypal

klownboy
Posts: 4463
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.8737 at 100% 2560x1440

Re: Using variable in a script sub

Post by klownboy »

Hi highend, sorry for being a pain. Adding a very short wait of 200 millisecond seems to have fixed the temporary "bad image" coming up on the thumbnails.

Unfortunately, another issue has raised it's ugly head. All the portrait type photos which have, as an example, a size of 2592x3888 are actually in Exif or Meta data 3888x2592 since they're essentially a rotated photo. The corresponding "Orientation" in Irfanview Exif data or in XY Meta data is "Right top" as opposed to a normal landscape of "Top Left". So because the script is detecting the wrong size photo (since it's using Exif data), the cropping ends up being very wrong. This applies for either my Panasonic or Canon Rebel photos in portrait. This little script to automate cropping is turning out to be a headache, but fun. After some research I discovered I could detect not only the camera make and model via XY's property command, but also the "Orientation" using property("#245", <curitem>). It displays "Normal" if in Landscape and "Rotate 270 degrees" if in portrait mode for any camera. So hopefully by using this property command I can filter out the portrait pics and the difficult part may end up being how to properly crop them with the reverse Exif data.
Again thanks so much,
Ken

Thanks serendipity for Properties-v2.xys.
Thanks Don on the pointer to refreshing single thumbnails when needed.

Post Reply