5391 posts
  • Australia
  • Bought between 100 and 499 items
  • Envato Studio (Microlancer) Beta Tester
  • Exclusive Author
  • Has been a member for 4-5 years
  • Interviewed on the Envato Notes blog
  • Referred between 1 and 9 users
  • Sold between 1 000 and 5 000 dollars
Australia says

Found this which can crop down to a pre defined scale, but buggered if i can get it to do the following:

1. if image is under 680px x 400px ( example ) then save at scale 1:1 on an image with dims. 680px x 400px

If the image is larger than the above I can kind of get it working

Script used: http://www.codeforest.net/upload-crop-and-resize-images-with-php

5391 posts
  • Australia
  • Bought between 100 and 499 items
  • Envato Studio (Microlancer) Beta Tester
  • Exclusive Author
  • Has been a member for 4-5 years
  • Interviewed on the Envato Notes blog
  • Referred between 1 and 9 users
  • Sold between 1 000 and 5 000 dollars
Australia says

Sample: here

As you can see if i upload a huge image, the resize function works a dream.

If the image is under the dimensions 680px x 400px it doesnt handle it so well.

619 posts
  • Exclusive Author
  • Has been a member for 1-2 years
  • Sold between 1 000 and 5 000 dollars
  • Most Wanted Bounty Winner
  • Bought between 1 and 9 items
  • Referred between 10 and 49 users
  • Europe
abstract-labs says

@abstractlabs that works great if the aspect ratios are all the same, but obviously they wont be lol. Hence the dilemma

Sorry I missed the point a little bit… I would do this: leave your uploader as it is (so your customers can upload any image), resize and crop the images with php on the fly as needed and display them with an “img-responsive” class.

Does your uploader handle max file size? If so it should be fine

5391 posts
  • Australia
  • Bought between 100 and 499 items
  • Envato Studio (Microlancer) Beta Tester
  • Exclusive Author
  • Has been a member for 4-5 years
  • Interviewed on the Envato Notes blog
  • Referred between 1 and 9 users
  • Sold between 1 000 and 5 000 dollars
Australia says

Appreciate your replies.

This guy has the same issue. http://stackoverflow.com/questions/3209206/resize-an-image-to-an-exact-size-retain-aspect-and-fill-any-space-in-php?rq=1

< still trying to figure out a workaround. If it was non responsive it would not be an issue whatoever. But because its bleeding responsive, the image size cannot be declared, so we have to rely on the physical width and height of the image to force responsive resizing.

Because the parent handler is reponsive based on column resizing, the image must fit within that scale. If you view the link I posted earlier to a theme we are using, and resize your browser you will see what I am talking about.

My criteria is simple.

If image is larger than 680×400 resize/crop to this size keeping aspect ratio and rewrite to new image at size 680×400 and fill in background will fill.

Likewise if image is smaller that 680×400 copy to new image of size 680×400 and fill background with color.

It sounds so simple, and if anyone wants to take a stab at it, I will pay as this must be a much needed script for users now embarking on responsive layouts.

Its all well and good for theme developers to shove in one perfect sized image that scales well as the browser resizes, but in actuality, we all deal with images from gazillions of places, and a php solution would negate the requirement for inhouse resizing.

Ste

619 posts
  • Exclusive Author
  • Has been a member for 1-2 years
  • Sold between 1 000 and 5 000 dollars
  • Most Wanted Bounty Winner
  • Bought between 1 and 9 items
  • Referred between 10 and 49 users
  • Europe
abstract-labs says

Hey Steve I edited your upload.php, try the following:

require_once('ImageManipulator.php');

if ($_FILES['fileToUpload']['error'] > 0) {
    echo "Error: " . $_FILES['fileToUpload']['error'] . "<br />";
} else {
    // array of valid extensions
    $validExtensions = array('.jpg', '.jpeg', '.gif', '.png');
    // get extension of the uploaded file
    $fileExtension = strrchr($_FILES['fileToUpload']['name'], ".");
    // check if file Extension is on the list of allowed ones
    if (in_array($fileExtension, $validExtensions)) {
        $newNamePrefix = time() . '_';
        $manipulator = new ImageManipulator($_FILES['fileToUpload']['tmp_name']);
        $width  = $manipulator->getWidth();
        $height = $manipulator->getHeight();

        // if width is >= 680px we need to resample the image before cropping
        // let's find the new height based on width scale amount
        $newHeight = ($height*680) / $width;

        if ($width >= 680) {
            $newImage = $manipulator->resample(680, $newHeight, $constrainProportions = true);
            //$centreX = round($width / 2);
            $centreX = 340;
            $centreY = round($newHeight / 2);
            // our dimensions will be 680x400
            $x1 = $centreX - 340; // 340 / 2
            $y1 = $centreY - 200; // 200 / 2

            $x2 = $centreX + 340; // 340 / 2
            $y2 = $centreY + 200; // 200 / 2

            // center cropping to 680x400
            $newImage = $manipulator->crop($x1, $y1, $x2, $y2);

        } else { //if the image is smaller we don't need to resample/crop it, we can just increase the canvas size and place the image right in the middle

            if($height > 400) { // you never know, users may upload 100x700px images, and it would be a mess, so let's resize before proceeding
                $newWidth = ($width*400) / $height;
                $newImage = $manipulator->resample($newWidth, 400, $constrainProportions = true);
            }
            $newImage = $manipulator->enlargeCanvas(680, 400, $rgb = array("255","255","255"), $xpos = null, $ypos = null);
        }

        // saving file to uploads folder
        $manipulator->save('uploads/' . $newNamePrefix . $_FILES['fileToUpload']['name']);
        echo 'Done ...<a href="files.php">View Uploads</a>';
    } else {
        echo 'You must upload an image...try <a href="index.php">again</a>';
    }
}

What do you think?

The imageManipulator class is pretty interesting, nice finding! ;)

5391 posts
  • Australia
  • Bought between 100 and 499 items
  • Envato Studio (Microlancer) Beta Tester
  • Exclusive Author
  • Has been a member for 4-5 years
  • Interviewed on the Envato Notes blog
  • Referred between 1 and 9 users
  • Sold between 1 000 and 5 000 dollars
Australia says

haha goodonya, I was just redoing a total new include to exclue the bloody images because it was so doing my head in ! Will give it a try now, sincerely appreciate that.

Yeah thats a pretty nifty class huh ( will report back asap )

2957 posts
  • Australia
  • Community Moderator
  • Elite Author
  • Author had a Free File of the Month
  • Most Wanted Bounty Winner
  • Author had a File in an Envato Bundle
  • Has been a member for 5-6 years
  • Contributed a Blog Post
  • Repeatedly Helped protect Envato Marketplaces against copyright violations
+10 more
dtbaker Volunteer moderator says

If the above doesn’t work then feel free to give this a try. It’s the image resizing class I’ve used in a few little jobs:

$image_path = "/path/to/image.jpeg";
$resized_image = "/path/to/image.resized.jpeg";
$is = new ImageSizer("/tmp/");
$is->loadImage($image_path);
$is->_defaultColor = array(255,255,255); // default background fill color 
$crop_method = "f"; // options here are false, "f" or "c" (f will fill, c will crop, false will nfi? try them out)
$is->resizeImage($width, $height, $crop_method);
//$is->changeFormat("jpeg");
//$is->addWatermark($size['watermark']['image'],25);
$is->saveToFile($resized_image);

class ImageSizer {

  var $_baseDir;
  var $_baseImg;
  var $_imgData;

  var $_newImg;
  var $_newData;
  var $_newFormat;

  var $_loadPath;
  var $_defaultColor = array(255,255,255);

  var $keepAspectRatio;
  var $makeBigger;

  function ImageSizer($baseDir) {
    $this->changeBaseDir($baseDir);
    $this->keepAspectRatio = true;
    $this->makeBigger = false;
  }

  function changeBaseDir($baseDir) {
    $this->_baseDir = $baseDir;
  }

  function setDefaultColor($r, $g, $b) {
    $this->_defaultColor = array($r, $g, $b);
  }

  function changeFormat($str) {
    $str = strtolower($str);
    if ($str == 'jpg') $str = "jpeg";
    $acceptable_formats = array('jpeg', 'gif', 'png');
    if (!in_array($str, $acceptable_formats)) return false;
    $this->_newFormat = $str;
  }

  function loadImage($imgPath) {
   // $this->_imgData = getimagesize($this->_baseDir. $imgPath);
    $this->_imgData = getimagesize( $imgPath);
    $this->_imgData['funcType'] = preg_replace('#image/#i', '', $this->_imgData['mime']);
    $acceptable_formats = array('jpeg', 'gif', 'png');
    if (!in_array($this->_imgData['funcType'], $acceptable_formats)) return false;
    $this->_newData = $this->_imgData;
    $funcName = 'imagecreatefrom' . $this->_imgData['funcType'];
    //$this->_newImg = $this->_baseImg  = $funcName($this->_baseDir. $imgPath);
    $this->_newImg = $this->_baseImg  = @$funcName( $imgPath);
    if(!$this->_baseImg){
        echo "<br /> Failed on this image $imgPath <br /> ";
        return false;
    }
    $this->_loadPath = $imgPath;
    return true;
  }
    /*function genImageData(){
        $funcName = 'image'.$this->getNewType();
           $data = $funcName($this->_newImg ? $this->_newImg : $this->_baseImg);
        return $data;
    }*/
  function resizeImage($w, $h, $crop=false) {
    $current_w = $this->getWidth();
    $current_h = $this->getHeight();

    $src_x = $src_y = 0;
    $dst_x = $dst_y = 0;

    if($w && $h && $crop=="f"){
        // fill in the image centre it in white.
        // all the src stuff stays the same, just changing the destination suff
        $src_x = 0;
        $src_y = 0; 
        $current_h = $current_h;
        $current_w = $current_w;

        // the destination stuff changes
        if($h && $w){
            $h_percent = $percent = $h / $current_h;
            $w_percent = $percent = $w / $current_w;
             $percent = min($h_percent, $w_percent);
        }else if($h){
            $h_percent = $percent = $h / $current_h;
             $percent = $h_percent;
        }else if($w){
            $w_percent = $percent = $w / $current_w;
             $percent = $w_percent;
        }
        $dst_w = $current_w * $percent;
        $dst_h = $current_h * $percent;

        $new_w = $w;
        $new_h = $h;
        // work out destination x and y points

        $dst_x = ($new_w - $dst_w)/2;
        $dst_y = ($new_h - $dst_h)/2;

    }else if($w && $h && $crop=="c"){
        $dst_w = $w;
        $dst_h = $h;
        $new_w = $w;
        $new_h = $h;
        // if the image we are tyring to crop is smaller than the crop request we dont do aynthing
        if($w > $current_w || $h > $current_h){
            // the image is smaller than we are trying to crop!
        }else{
            //the image is bigger on x and y axis.
            // check if we can fit horizontally
            $w_percent = $current_w/$w;
            $h_percent = $current_h/$h;
            if($w_percent < $h_percent){
                $src_x = 0;
                $src_y = ($current_h/2) - (($h * $w_percent)/2);
                $current_w = $current_w;
                $current_h = ($h * $w_percent);
            }else{
                $src_x = ($current_w/2) - (($w * $h_percent)/2);
                $src_y = 0;
                $current_w = ($w * $h_percent);
                $current_h = $current_h;
            }

        }

    }else if ($this->keepAspectRatio) {
      $percent = 1;
     // if ($current_w > $w || $current_h > $h || $this->makeBigger) {
     $do_resize=false;
     if($w && $current_w > $w){
         $do_resize=true;
     }else if($h && $current_h > $h){
         $do_resize=true;
     }else if($w && $current_w < $w && $this->makeBigger){
         $do_resize=true;
     }else{
         // imaeg is alreaedy smaller than requested size
     }
      if (  $do_resize ) {
          if($h && $w){
            $h_percent = $percent = $h / $current_h;
            $w_percent = $percent = $w / $current_w;
             $percent = min($h_percent, $w_percent);
        }else if($h){
            $h_percent = $percent = $h / $current_h;
             $percent = $h_percent;
        }else if($w){
            $w_percent = $percent = $w / $current_w;
             $percent = $w_percent;
        }
      }

        $dst_w = $new_w = $current_w * $percent;
        $dst_h = $new_h = $current_h * $percent;
    } else{
        $dst_w = $new_w = $w;
        $dst_h = $new_h = $h;
    }

    $this->_newImg = ImageCreateTrueColor($new_w, $new_h);
    $this->_newData = array($new_w, $new_h);

    if ($this->getNewType() == 'png' || $this->getNewType() == 'gif') { // This preserves the transparency
        $trnprt_indx = imagecolortransparent($this->_baseImg);
        // If we have a specific transparent color
        if ($trnprt_indx >= 0) {
            // Get the original image's transparent color's RGB values
            $trnprt_color    = imagecolorsforindex($this->_baseImg, $trnprt_indx);
            // Allocate the same color in the new image resource
            $trnprt_indx    = imagecolorallocate($this->_newImg, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
            // Completely fill the background of the new image with allocated color.
            imagefill($this->_newImg, 0, 0, $trnprt_indx);
            // Set the background color for new image to transparent
            imagecolortransparent($this->_newImg, $trnprt_indx);
        }
        // Always make a transparent background color for PNGs that don't have one allocated already
        elseif ($this->getNewType() == 'png') {
            // Turn off transparency blending (temporarily)
            imagealphablending($this->_newImg, false);
            // Create a new transparent color for image
            $color = imagecolorallocatealpha($this->_newImg, 255, 255, 255, 127);
            // Completely fill the background of the new image with allocated color.
            imagefill($this->_newImg, 0, 0, $color);
            // Restore transparency blending
            imagesavealpha($this->_newImg, true);
        }
        //imageAlphaBlending($this->_newImg, false);
        //imageSaveAlpha($this->_newImg, true);
    } else { // This is if converting from PNG to another image format
      list($r, $g, $b) = $this->_defaultColor;
      $color = imagecolorallocate($this->_newImg, $r, $g, $b);
      imagefilledrectangle($this->_newImg, 0,0, $new_w, $new_h, $color);
    }
                                                                                    // dst_w   dst_h   src_w       src_h
    imagecopyresampled($this->_newImg, $this->_baseImg, $dst_x, $dst_y,$src_x,$src_y, $dst_w, $dst_h, $current_w, $current_h);
    return true;
  }

  function showImage() {
    header('Content-type: ' . $this->getNewMime());
    $funcName = 'image'.$this->getNewType();
    $funcName($this->_newImg ? $this->_newImg : $this->_baseImg);
  }

  function saveToFile($fileloc) {
    $funcName = 'image'.$this->getNewType();
    $quality = 100;
    if($this->getNewType() == 'png')$quality = 0;
    $funcName($this->_newImg ? $this->_newImg : $this->_baseImg, $fileloc, $quality);
  }

  function addWatermark($pngloc,$offset_x=0) {
      $overlay = imagecreatefrompng($pngloc);
    imageAlphaBlending($overlay, false);
    imageSaveAlpha($overlay, true);
      imagecopy($this->_newImg, $overlay, (imagesx($this->_newImg))-(imagesx($overlay)+$offset_x), (imagesy($this->_newImg))-(imagesy($overlay)), 0, 0, imagesx($overlay), imagesy($overlay));
  }

  function getBaseDir() { return $this->_baseDir; }

  function getWidth() { return $this->_imgData[0]; }
  function getHeight() { return $this->_imgData[1]; }
  function getMime() { return $this->_imgData['mime']; }
  function getType() { return $this->_imgData['funcType'];}

  function getNewWidth() { return $this->_newData[0]; }
  function getNewHeight() { return $this->_newData[1]; }
  function getNewMime() {return $this->_newFormat ? 'image/' . $this->_newFormat : $this->_imgData['mime'];}
  function getNewType() {return $this->_newFormat ? $this->_newFormat : $this->_imgData['funcType'];}

}
5391 posts
  • Australia
  • Bought between 100 and 499 items
  • Envato Studio (Microlancer) Beta Tester
  • Exclusive Author
  • Has been a member for 4-5 years
  • Interviewed on the Envato Notes blog
  • Referred between 1 and 9 users
  • Sold between 1 000 and 5 000 dollars
Australia says

Holy Guacamole ( not sure on spelling ) cheers Dave

5391 posts
  • Australia
  • Bought between 100 and 499 items
  • Envato Studio (Microlancer) Beta Tester
  • Exclusive Author
  • Has been a member for 4-5 years
  • Interviewed on the Envato Notes blog
  • Referred between 1 and 9 users
  • Sold between 1 000 and 5 000 dollars
Australia says

Ok guys abstract-labs solution seriously fitted my remit. And I can honestly say this is perhaps the most important file we have at the moment in our web developer arsenal.

We can now deploy, dynamic responsive sites with proprietary image uploaders and handle image manipulation server side. So that we publish uniform grids.

Many thanks to both Abstract-Labs and Dave for your help.

Regards Ste

619 posts
  • Exclusive Author
  • Has been a member for 1-2 years
  • Sold between 1 000 and 5 000 dollars
  • Most Wanted Bounty Winner
  • Bought between 1 and 9 items
  • Referred between 10 and 49 users
  • Europe
abstract-labs says

Great, glad to hear that Steve, no problem! Of course some more testing is needed.

One more thing: you may want to add some kind of control to check if a user uploads an image which is too small, I don’t think it would be good to let users upload 50×50px images, unless they know what they’re doing.

I love it when a php plan comes togheter :D

Andrew

by
by
by
by
by
by