Welcome Guest, Not a member yet? Register   Sign In
image_lib - resizing transparent png24
#11

[eluser]John Morton[/eluser]
BorisK,

Your solution looks exactly like something I need. Pardon the newbie question, but where do these functions you've posted live? Are they in a model or controller?

-John Morton
#12

[eluser]BorisK[/eluser]
John, those functions were not built for CodeIgniter but for general PHP code. Let me know if you problems with porting it to CI.
#13

[eluser]RaiNnTeaRs[/eluser]
I always get this message, what is that supposed to mean ? Thankx

Message: imagecreatefromjpeg() [function.imagecreatefromjpeg]: gd-jpeg, libjpeg: recoverable error: Premature end of JPEG file

Filename: libraries/Image_lib.php
#14

[eluser]John Morton[/eluser]
I'm still fighting with it actually. The way I've currently been resizing images is using CI's built in framework and it's working except when I have a PNG (or GIF?) that has a transparency. Here's what I've got which lives in my model.

You'll see I've got my resizing happening in this one big function. I like the idea of using ResizeImage as in your post, but need some advice. Any advice is greatly appreciated. -John

Code:
function updateHomeImage($myImageFromForm)
    {
        $shrinkdimensions = 250;
        $enlargedimensions = 500;
        $config['upload_path'] = './uploads/home/original/';
        $config['allowed_types'] = 'gif|jpg|png';
        $config['max_size'] = '200';
        $config['max_width'] = '1000';
        $config['max_height'] = '1000';
        $config['encrypt_name'] = false;
        $config['remove_spaces'] = true;
        $this->load->library('upload', $config);
        
        if ($this->upload->do_upload($myImageFromForm)){
            foreach ($this->upload->data() as $item => $v){
            # print_r("item=".$item." v=".$v."<br />");
            # returns lots of info about the uploaded file which is stored in the data variable belowe
            $data[$item] = $v;
        }
        # storing file details in toupdatedb to be inserted into database
        $toupdatedb->primaryoriginal = $data['file_name'];
        
        $this->orig_width = $data['image_width'];
        $this->orig_height = $data['image_height'];
        
        // Start image_lib to allow resizing
        $this->load->library('image_lib');
        $imgfile = $data['full_path'];
        $imgpath = $data['file_path'];
        $filename = $data['file_name'];
        $config['image_library'] = 'GD2';
        $config['source_image'] = $imgfile;
        $config['maintain_ratio'] = TRUE;
        $config['create_thumb'] = false;
        # need to find base_path so of uploaded file to store resized images in sibling directories
        $base_path = substr($imgpath, 0, strripos($imgpath, 'original/'));
    
        #// Make Small resize
        if (($this->orig_width >= $shrinkdimensions) || ($this->orig_height >= $shrinkdimensions))
              {
            //print_r("small sizeifier fired <br />");
              # $this-ResizeImage(250, 250); <- didn't work, so commented out
        
            $config['new_image'] = $base_path. 'small/'.$filename;
            $config['width'] = $shrinkdimensions;
            $config['height'] = $shrinkdimensions;
            $config['master_dim'] = 'width'; // this sets the resizer to default to height when preserving the ratio
            $this->image_lib->initialize($config);
            if ($this->image_lib->resize())
                {        
                //print_r("success small  <br />");
                $toupdatedb->primarysmall = $filename;
                } else {
                $toupdatedb->primarysmall = NULL;
                  //print_r("small sizeifier DIDN'T fire <br />");
            };

        // Make Large resize            
        if (($this->orig_width >= $enlargedimensions) || ($this->orig_height >= $enlargedimensions))
            {
            //print_r("large sizeifier fired");
            $config['new_image'] = $base_path. 'large/'.$filename;
            $config['width'] = $enlargedimensions;
            $config['height'] = $enlargedimensions;
            $this->image_lib->initialize($config);
            if ($this->image_lib->resize())
            {
            //print_r("success large /n <br />");
            $toupdatedb->primarylarge = $filename;
            } else {
            $toupdatedb->primarylarge = NULL;
            //print_r("large sizeifier DIDN'T fire <br />");
        }
        
        $this->db->update('home', $toupdatedb);
        
        return $data;
        }    else    {
            return FALSE;
        }
    }
# not sure how to call the following functions to make them work with updateHomeImage using img_lib above
function ResizeImage($newWidth, $newHeight)
    {
        $this->newWidth = $newWidth;
        $this->newHeight = $newHeight;
        $this->dest_image = imagecreatetruecolor($this->newWidth, $this->newHeight);
        $this->ImageSetAlpha();
        imagecopyresampled($this->dest_image, $this->src_image, 0, 0, 0, 0,    $this->newWidth, $this->newHeight, imagesx($this->src_image), imagesy($this->src_image));
        $this->src_image = $this->dest_image;
    }

function ImageSetAlpha ()
    {
        $background = imagecolorallocate($this->dest_image, 0, 0, 0);
        ImageColorTransparent($this->dest_image, $background);
        imagealphablending($this->dest_image, false);
    }

It seems like I need a Resize function that returns a reference to the new resized file so I can store it in my database. Does this mean I need to have a resize function that not only takes the x and y dimensions, but a reference to the file that needs to be resized already sitting on my server?
#15

[eluser]Ornoc[/eluser]
I believe I have the 24bit PNG transparency issue solved. It requires first creating a 100% transparent color, and then filling the new image before the imagecopyresampled.

I have made a custom library that replaces the image_lib->image_process_gd function and adds the relevant code. Just put it in your system/application/libraries directory and it should be good to go.

My_Image_lib.zip

Unless there is some big performance problem with doing this, it seems like this could easily be integrated into the next CI update.

For those interested, here is the relevant code:
Code:
imageAlphaBlending($dst_img, false);
imageSaveAlpha($dst_img, true);
$trans_colour = imagecolorallocatealpha($dst_img, 0, 0, 0, 127);
imagefill($dst_img, 0, 0, $trans_colour);
In my Image_lib it would go right after line 520.
#16

[eluser]John Morton[/eluser]
Ornoc,

I appreciate the reply. I'm in the middle of another project right now, but will try to implement your fix as soon as I get back on my CI project. I'll post about my results then. Thanks.

-John
#17

[eluser]Velin[/eluser]
[quote author="mandelkern" date="1209157712"]I found a solution at http://www.webdeveloper.com/forum/showthread.php?t=178210.

Nearly at line

514 - $dst_img = $create($this->width, $this->height);

I changed the code this way:

//$dst_img = $create($this->width, $this->height);

/* TRANSPARENT PNG */
$dst_img = imagecreatetruecolor($this->width, $this->height);
$transparent = imagecolorallocatealpha($dst_img,0,255,0,127);
imagefill($dst_img,0,0,$transparent);

$copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);

imageAlphaBlending($dst_img, false);
imageSaveAlpha($dst_img, true);

..and now it works.[/quote]

This was very helpful, thank you.
Why this is not the normal behavior of the image_lib is beyond me.
#18

[eluser]rip_pit[/eluser]
Great!
here's how someone can use this without modifying the core function (easiest for updating)

Do not edit /system/librairies/Image_lib.php
Instead, create a new file in your /application/libraries/ folder
And call it MY_Image_lib.php

Copy and paste this code :

/application/libraries/MY_Image_lib.php
Code:
&lt;?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
* CodeIgniter Image Manipulation Class fixed
* fixed method "image_process_gd" to keep png transparency when resizing
* more info : http://ellislab.com/forums/newreply/77836/
*/
class MY_Image_lib extends CI_Image_lib {

  function MY_Image_lib() {
    parent::CI_Image_lib();
  }

  /**
   * FIXED function to keep transparency
   * Image Process Using GD/GD2
   *
   * This function will resize or crop
   *
   * @access    public
   * @param    string
   * @return    bool
   */
  function image_process_gd($action = 'resize') {
    $v2_override = FALSE;

    // If the target width/height match the source, AND if the new file name is not equal to the old file name
    // we'll simply make a copy of the original with the new name... assuming dynamic rendering is off.
    if ($this->dynamic_output === FALSE) {
      if ($this->orig_width == $this->width AND $this->orig_height == $this->height) {
        if ($this->source_image != $this->new_image) {
          if (@copy($this->full_src_path, $this->full_dst_path)) {
            @chmod($this->full_dst_path, DIR_WRITE_MODE);
          }
        }

        return TRUE;
      }
    }

    // Let's set up our values based on the action
    if ($action == 'crop') {
      //  Reassign the source width/height if cropping
      $this->orig_width = $this->width;
      $this->orig_height = $this->height;

      // GD 2.0 has a cropping bug so we'll test for it
      if ($this->gd_version() !== FALSE) {
        $gd_version = str_replace('0', '', $this->gd_version());
        $v2_override = ($gd_version == 2) ? TRUE : FALSE;
      }
    } else {
      // If resizing the x/y axis must be zero
      $this->x_axis = 0;
      $this->y_axis = 0;
    }

    //  Create the image handle
    if (!($src_img = $this->image_create_gd())) {
      return FALSE;
    }

    //  Create The Image
    //
    //  old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"
    //  it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment
    //  below should that ever prove inaccurate.
    //
    //  if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor') AND $v2_override == FALSE)
    if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor')) {
      $create = 'imagecreatetruecolor';
      $copy = 'imagecopyresampled';
    } else {
      $create = 'imagecreate';
      $copy = 'imagecopyresized';
    }

    // CODE:
    //        $dst_img = $create($this->width, $this->height);
    //        $copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);
    // REPLACED WITH: start
    // TRANSPARENT PNG
    $dst_img = imagecreatetruecolor($this->width, $this->height);
    $transparent = imagecolorallocatealpha($dst_img, 0, 255, 0, 127);
    imagefill($dst_img, 0, 0, $transparent);
    $copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);
    imageAlphaBlending($dst_img, false);
    imageSaveAlpha($dst_img, true);
    // REPLACED WITH: end

    //  Show the image
    if ($this->dynamic_output == TRUE) {
      $this->image_display_gd($dst_img);
    } else {
      // Or save it
      if (!$this->image_save_gd($dst_img)) {
        return FALSE;
      }
    }

    //  Kill the file handles
    imagedestroy($dst_img);
    imagedestroy($src_img);

    // Set the file to 777
    @chmod($this->full_dst_path, DIR_WRITE_MODE);

    return TRUE;
  }

}

/* End of file MY_Image_lib.php */
/* Location: ./application/libraries/MY_Image_lib.php */


Now when you'll call Image_lib as usual, this file be auto loaded and override the core functions, using the ones defined in this new file.

read more about extending CI :http://ellislab.com/codeigniter/user-guide/general/creating_libraries.html

I hope i helped a bit because this fix helped me a lot !




Theme © iAndrew 2016 - Forum software by © MyBB