Photo Cropper

Discuss and share scripts and script files...
Post Reply
klownboy
Posts: 4140
Joined: 28 Feb 2012 19:27

Photo Cropper

Post by klownboy »

Hi, Photo Crop is my first real script I've posted. Simple, but I hope you can get some use out of it. Photo crop may come in handy for quickly converting your personnal photos or wallpapers downloaded from the internet from one aspect ratio to another. Most often I use it to crop personnal phots to the aspect ratio of my computer monitors. The script will work best saved to a customizable toolbar button (left or right click). Select one or more images in XYplorer, click the CBT, and select the aspect ratio you want to change the photo "TO". It does this by cropping the image in either the x-axis or y-axis as appropriate, not resizing them. So the original quality of the image is not lost or reduced by shrinking or expanding the image. Though it works for multiple selected images, in most cases you'll want to evaluate where the cropping will occur so you'll want to look closely at the picture (or thumbnail) to determine if you want to offset the default center crop in either the x or y axis as appropriate. The script uses Irfanview to perform the actual cropping so you will have to point to where you have it installed or install it first if you don't already (i.e., modify $g_IrfanPath=D:\graphics\irfanview...near the end of the script). Please change those icons in the headers. I don't use these. For this uploaded script, I used icons built-in to XYplorer so everyone would have them. Beware of wrapping.
PhotoCrop.jpg
PhotoCrop.jpg (33.23 KiB) Viewed 2788 times

Code: Select all

 // Photo crop may come in handy for quickly converting your personnal photos or wallpapers downloaded from the internet from one aspect ratio to another.
 // The script will work best saved to a customizable toolbar button (left or right click). Select one or more images in XYplorer, click the CBT, and select the aspect ratio you want to change the photo "TO". 
 // It does this by cropping the image in either the x-axis or y-axis as appropriate, not resizing them. So the original quality of the image is not lost or reduced by shrinking or expanding the image.
 // Though it works for multiple selected images, in most cases you'll want to evaluate where the cropping will occur so you'll want to look closely at the picture or thumbnail to determine if you want to offset the default center crop in either the x or y axis as appropriate.
 // The script uses Irfanview to perform the actual cropping so you will have to point to where you have it installed or install it first if you don't already (i.e., modify $g_IrfanPath=D:\graphics\irfanview...near the end of the script)
 // Please change those icons in the headers.  I don't use these.  For this uploaded script, I used icons built-in to XYplorer so everyone would have them.
 // Thanks to Stefan, SkyFrontier, highend, and PeterH for getting me through some issues.
 
" CROP PHOTO   to   ASPECT RATIO|:cut"             // see sub "_ExecuteIV" to modify Irfanview path to suit your installation
   load self(file);
"      16x9 or 1.77 (e.g., 1920x1080)|:views";      // maintains the highest possible file size and only crops to achieve a 16x9 aspect ratio;
 
  global $x_crop, $y_crop, $xy, $rotate, $orig_width, $orig_height, $orig_ratio, $width, $height;
  global $file, $FileChkReturn, $fn;

  foreach($token, <get selecteditemspathnames |>) {
   $file = $token;
   $xy = "16x9";
   sub "_FileChk";
  if ($FileChkReturn == "1"){
                                                             // when going "TO" 16x9 we will always be cropping in the y axis at least for standard photography
    $height = ($orig_width * 9) / 16;                      // echo "Test 1: New height is ". $height ."";
    $y_total_crop = round ($orig_height - $height);
    $y_crop = round ($y_total_crop / 2);                   // msg "Crop amount is ". $y_crop ."";
 
    $y_crop = input("Crop ". $fn ." to a ". $xy ." aspect ratio.","Crop offset [y] vertically down from upper left corner 0,0.<crlf>Enter number from 1 to ". $y_total_crop .", e.g., ". $y_crop ." centers crop.", $y_crop, "s", ,450,300);
    $width = $orig_width; $x_crop = "0"; sub "_ExecuteIV";
    }
  }
    
"      8x5 or 1.6 (e.g., 1920x1200)|:preview";     // maintains the highest possible file size and only crops to 8x5 aspect ratio
  global $x_crop, $y_crop, $xy, $rotate, $orig_width, $orig_height, $orig_ratio, $width, $height;
  global $file, $FileChkReturn, $fn;
  foreach($token, <get selecteditemspathnames |>) {
    $file = $token;
    $xy = "8x5";
    sub "_FileChk";
   if ($FileChkReturn == "1"){

    if ($orig_ratio > 1.6) {                // If ratio is > 1.6 which is an 8x5, we must crop on the x axis (e.g., Panasonic camera 4320 x 2430 (16x9) to a 8x5)
       $width = round (($orig_height * 8) / 5);
       $x_total_crop = round ($orig_width - $width);
       $x_crop = round ($x_total_crop / 2);                 // msg "Crop amount is ". $x_crop ."";

       $x_crop = input("Crop ". $fn ." to a ". $xy ." aspect ratio.","Crop offset [x] horizontally across from upper left corner 0,0.<crlf>Enter number from 1 to ". $x_total_crop .", e.g., ". $x_crop ." centers crop.", $x_crop, "s", ,300,250);
       $height = $orig_height; $y_crop = "0"; sub "_ExecuteIV";                   //$height is actually the same in this case since we are cropping [x]
       }
     else {
       $height = ($orig_width * 5) / 8;                     //echo New height is ". $height ."";
       $y_total_crop = round ($orig_height - $height);
       $y_crop = round ($y_total_crop / 2);                 //msg "Crop amount is ". $y_crop ."";
   
       $y_crop = input("Crop ". $fn ." to a ". $xy ." aspect ratio.","Crop offset [y] vertically down from upper left corner 0,0.<crlf>Enter number from 1 to ". $y_total_crop .", e.g., ". $y_crop ." centers crop.", $y_crop, "s", ,300,250);
       $width = $orig_width; $x_crop = "0"; sub "_ExecuteIV";
       }
     }
   }
    
"      3x2 or 1.5 (e.g., 1800x1200)|:browsenetwork";     // maintains the highest possible file size and only crops to 3x2 aspect ratio
  global $x_crop, $y_crop, $xy, $rotate, $orig_width, $orig_height, $orig_ratio, $width, $height;
  global $file, $FileChkReturn, $fn;
  foreach($token, <get selecteditemspathnames |>) {
    $file = $token;
    $xy = "3x2";
    sub "_FileChk";
   if ($FileChkReturn == "1"){

    if ($orig_ratio > 1.5) {                // If ratio is > 1.5 which is an 3x2, we must crop on the x axis (e.g., 4320 x 2430 (16x9) to a 4x3)
       $width = round (($orig_height * 3) / 2);
       $x_total_crop = round ($orig_width - $width);
       $x_crop = round ($x_total_crop / 2);                 // msg "Crop amount is ". $x_crop ."";

       $x_crop = input("Crop ". $fn ." to a ". $xy ." aspect ratio.","Crop offset [x] horizontally across from upper left corner 0,0.<crlf>Enter number from 1 to ". $x_total_crop .", e.g., ". $x_crop ." centers crop.", $x_crop, "s", ,300,250);
       $height = $orig_height; $y_crop = "0"; sub "_ExecuteIV";                   //$height is actually the same in this case since we are cropping [x]
       }
     else {
       $height = ($orig_width * 2) / 3;                     //echo New height is ". $height ."";
       $y_total_crop = round ($orig_height - $height);
       $y_crop = round ($y_total_crop / 2);                 //msg "Crop amount is ". $y_crop ."";
   
       $y_crop = input("Crop ". $fn ." to a ". $xy ." aspect ratio.","Crop offset [y] vertically down from upper left corner 0,0.<crlf>Enter number from 1 to ". $y_total_crop .", e.g., ". $y_crop ." centers crop.", $y_crop, "s", ,300,250);
       $width = $orig_width; $x_crop = "0"; sub "_ExecuteIV";
       }
     }
   }

"      4x3 or 1.33 (e.g., 1600x1200)|:viewthumbs";          // maintains the highest possible file size and only crops to 4x3 aspect ratio

  global $x_crop, $y_crop, $xy, $orig_width, $orig_height, $orig_ratio, $width, $height;
  global $file, $FileChkReturn, $fn;
  foreach($token, <get selecteditemspathnames |>) {
    $file = $token;
    $xy = "4x3";
    sub "_FileChk";
  if ($FileChkReturn == "1"){

    if ($orig_ratio > 1.33) {                                // If ratio is > 1.33 which is an 4x3, we must crop on the x axis (e.g., Panasonic camera 4320 x 2430 (16x9) to a 4x3)
       $width = round (($orig_height * 4) / 3);
       $x_total_crop = round ($orig_width - $width);
       $x_crop = round ($x_total_crop / 2);                  //msg "Crop amount is ". $x_crop ."";

       $x_crop = input("Crop ". $fn ." to a ". $xy ." aspect ratio.","Crop offset [x] horizontally across from upper left corner 0,0.<crlf>Enter number from 1 to ". $x_total_crop .", e.g., ". $x_crop ." centers crop.", $x_crop, "s", ,300,250);
       $height = $orig_height; $y_crop = "0"; sub "_ExecuteIV";                   //$height is actually the same in this case since we are cropping [x]
       }
    else {
       $height = ($orig_width * 3) / 4;                      //msg "New height is ". $height ."";
       $y_total_crop = round ($orig_height - $height);               //msg "Total Crop amount is ". $y_total_crop ."";
       $y_crop = round ($y_total_crop / 2);                  //msg "Crop amount is ". $y_crop ."";
   
       $y_crop = input("Crop ". $fn ." to a ". $xy ." aspect ratio.","Crop offset [y] vertically down from upper left corner 0,0.<crlf>Enter number from 1 to ". $y_total_crop .", e.g., ". $y_crop ." centers crop.", $y_crop, "s", ,300,250);
       $width = $orig_width; $x_crop = "0"; sub "_ExecuteIV";
       }
    }
  }
"-"
"Set current file as Wallpaper|:previewfull" run "D:\Graphics\IrfanView\i_view32.exe <curitem> /wall=3 /killmesoftly"
"Photo Metadata|:meta" #197;                    //C:\Windows\System32\shell32.dll /22

"_FileChk";
  global $file, $fn, $FileChkReturn, $token, $p, $xy, $rotate, $orig_width, $orig_height, $orig_ratio;
  $FileChkReturn = "1";
  End GetInfo("CountSelected") < 1, "No file(s) have been selected.";
   $fn=getpathcomponent($file, "file");
   $p = property("#11", $file);                            // determine if the file is a picture
  if ($p == "Picture") {                                   // checks properties to make sure it's an image/picture       
    $d = property(dimensions, $file);
    $rotate = property("#245", $file);
    $orig_width = property("ImageX", $file);               // another method,   $orig_width = gettoken($d, 1, " x ");
    $orig_height = property("ImageY", $file);
    $orig_ratio = round ($orig_width / $orig_height, 2);   // msg "Original ratio is ". $orig_ratio ."";

   if ($orig_width * $orig_height < 50000) {               // you can decrease this # to crop smaller images
       msg "Image, ". $fn ." is a bit small to crop ".<br>$d . " px!";
       $FileChkReturn = "0"; continue (2);    }

   if ($rotate != "Rotate 270 degrees") {                   // If picture is rotated, it's in "portrait" and will have a ratio < 1 and will not be a concern for these checks
     if ($orig_ratio == 1.33 AND ($xy == 4x3)) {            // checks to see if the picture is already in 4x3 aspect ratio
      msg "Image, ". $fn ." is already in a 4x3 aspect ratio, ". $d . " px!";
      $FileChkReturn = "0"; continue (2);     }
     if ($orig_ratio == 1.5 AND ($xy == 3x2)) {             // checks to see if the picture is already in 3x2 aspect ratio
      msg "Image, ". $fn ." is already in a 3x2 aspect ratio, ". $d . " px!";
      $FileChkReturn = "0"; continue (2);    }
     if ($orig_ratio == 1.6 AND ($xy == 8x5)) {             // checks to see if the picture is already in 8x5 aspect ratio
      msg "Image, ". $fn ." is already in a 8x5 aspect ratio, ". $d . " px!";
      $FileChkReturn = "0"; continue (2);    }
     if ($orig_ratio == 1.78 AND ($xy == 16x9)) {           // checks to see if the picture is already in 16x9 aspect ratio
      msg "Image, ". $fn ." is already in a<br>16x9 aspect ratio, ". $d . " px!";
      $FileChkReturn = "0"; continue (2);    }
     }
   else {                                                   //  Reverses X and Y axis since these photos are rotated 270 degrees- need to reverse for std crop calculations
      $orig_width = property("ImageY", $file);              //  Also, if we have a rotated pic, the above 3 "NOT rotated" checks do not apply
      $orig_height = property("ImageX", $file);
      $orig_ratio = round ($orig_width / $orig_height, 2);  // msg "Original ratio is ". $orig_ratio ."";
      }
    }
   else  {
     msg "The file, ". $fn ." is not an image so you can't crop it silly!";
     $FileChkReturn = "0"; continue (2);
     }
     
"_ExecuteIV";
  global $x_crop, $y_crop, $xy, $rotate, $width, $height, $file;
 
  $path=getpathcomponent($file, "path");
  $base=getpathcomponent($file, "base");
  $ext=getpathcomponent($file, "ext");
  $new_file = "$path\$base" . "_$xy.$ext";                   //     $new_file = gettoken ($file, 1,".")" . "_$xy.$ext";

  $g_IrfanPath="d:\graphics\irfanView\i_view32.exe";
  run """$g_IrfanPath"" $file /aspectratio /jpgq=100 /crop=($x_crop, $y_crop, $width, $height) /convert=$new_file", , 2,0;
  wait(500);                                                   //  If XY gives you a bad image on the thumbnail, the thumbnail probably needs to be refreshed.
Thanks to Stefan, SkyFrontier, highend, and PeterH for getting me through some issues.
Ken
Windows 11, 23H2 Build 22631.3447 at 100% 2560x1440

klownboy
Posts: 4140
Joined: 28 Feb 2012 19:27

Re: Photo Cropper

Post by klownboy »

I discovered the error check to determine if the file was a "picture" failed (i.e., it didn't return from the "sub" properly- probably because I had reworked the structure when I added a new aspect ratio yesterday) so I had to rewrite the sub slightly. I tweaked the original post. It's now a more positive check to ensure it's a picture. If you had already copied the code, you need only recopy the sub "_FileChk"; section.
Thanks,
Ken
Windows 11, 23H2 Build 22631.3447 at 100% 2560x1440

Post Reply