/** * Resize to $width x $height but keep the image proportion * * @param integer $width Max width * @param integer $height Max height * @param string $boundary Limit the scale action: drecrease or increase * only. If $boundary is NULL than don't limit * @param boolean $mutate Save the transformation in internal resource or * create new image and keep internal as is? * @return SimpleGdImage */ function scale($width, $height, $boundary = null, $mutate = true) { if (!is_resource($this->resource) || get_resource_type($this->resource) != 'gd') { return false; } $width = (int) $width > 0 ? (int) $width : 1; $height = (int) $height > 0 ? (int) $height : 1; $scale = min($width / $this->getWidth(), $height / $this->getHeight()); if ($boundary == self::BOUNDARY_DECREASE_ONLY) { if ($scale > 1) { if ($mutate) { return; } else { $new_image = new SimpleGdImage(); $new_image->createFromResource($this->resource); return $new_image; } // if } // if } elseif ($boundary == self::BOUNDARY_INCREASE_ONLY) { if ($scale < 1) { if ($mutate) { return; } else { $new_image = new SimpleGdImage(); $new_image->createFromResource($this->resource); return $new_image; } // if } // if } // if $new_width = floor($scale * $this->getWidth()); $new_height = floor($scale * $this->getHeight()); if ($this->getImageType() == IMAGETYPE_GIF) { $new_resource = imagecreate($new_width, $new_height); $originaltransparentcolor = imagecolortransparent($this->resource); if ($originaltransparentcolor >= 0 && $originaltransparentcolor < imagecolorstotal($this->resource)) { // for animated GIF, imagecolortransparent will return a color index larger // than total colors, in this case the image is treated as opaque ( actually // it is opaque ) $transparentcolor = imagecolorsforindex($this->resource, $originaltransparentcolor); $newtransparentcolor = imagecolorallocate($new_resource, $transparentcolor['red'], $transparentcolor['green'], $transparentcolor['blue']); // for true color image, we must fill the background manually imagefill($new_resource, 0, 0, $newtransparentcolor); // assign the transparent color in the thumbnail image imagecolortransparent($new_resource, $newtransparentcolor); } } else { $new_resource = imagecreatetruecolor($new_width, $new_height); imagealphablending($new_resource, false); imagesavealpha($new_resource, true); } // if imagecopyresampled($new_resource, $this->resource, 0, 0, 0, 0, $new_width, $new_height, $this->getWidth(), $this->getHeight()); if ($mutate) { imagedestroy($this->resource); $this->resource = $new_resource; $this->width = $new_width; $this->height = $new_height; return true; } else { $new_image = new SimpleGdImage(); $new_image->createFromResource($new_resource); return $new_image; } // if }
/** * Resize to $width x $height but keep the image proportion * * @param integer $width Max width * @param integer $height Max height * @param string $boundary Limit the scale action: drecrease or increase * only. If $boundary is NULL than don't limit * @param boolean $mutate Save the transformation in internal resource or * create new image and keep internal as is? * @return SimpleGdImage */ function scale($width, $height, $boundary = null, $mutate = true) { if (!is_resource($this->resource) || get_resource_type($this->resource) != 'gd') { if (is_null($this->source)) { return false; } } $width = (int) $width > 0 ? (int) $width : 1; $height = (int) $height > 0 ? (int) $height : 1; $mem_allowed = 1024 * 1024 * 6; // 6 MB $image_mem_usage = $this->getWidth() * $this->getHeight() * 4; // 4 bytes per pixel (RGBA) if ($image_mem_usage > $mem_allowed) { $im = imagecreatetruecolor($width, $height); $white = imagecolorallocate($im, 0xff, 0xff, 0xff); $black = imagecolorallocate($im, 0x0, 0x0, 0xff); @imagefill($im, 0, 0, $white); $s = $this->getWidth() . "x" . $this->getHeight(); @imagestring($im, 6, 10, 30, $s, $black); $this->resource = $im; $scale = 1; } else { $this->load(); $scale = min($width / $this->getWidth(), $height / $this->getHeight()); } if ($boundary == self::BOUNDARY_DECREASE_ONLY) { if ($scale >= 1) { if ($mutate) { return; } else { $new_image = new SimpleGdImage(); $new_image->createFromResource($this->resource); return $new_image; } // if } // if } elseif ($boundary == self::BOUNDARY_INCREASE_ONLY) { if ($scale <= 1) { if ($mutate) { return; } else { $new_image = new SimpleGdImage(); $new_image->createFromResource($this->resource); return $new_image; } // if } // if } // if $new_width = floor($scale * $this->getWidth()); $new_height = floor($scale * $this->getHeight()); switch ($this->getImageType()) { case IMAGETYPE_GIF: $new_resource = imagecreatetruecolor($new_width, $new_height); $colorcount = imagecolorstotal($this->resource); imagetruecolortopalette($new_resource, true, $colorcount); imagepalettecopy($new_resource, $this->resource); $transparentcolor = imagecolortransparent($this->resource); imagefill($new_resource, 0, 0, $transparentcolor); imagecolortransparent($new_resource, $transparentcolor); break; case IMAGETYPE_PNG: $new_resource = imagecreatetruecolor($new_width, $new_height); $transparent_color_index = imagecolortransparent($this->resource); if ($transparent_color_index >= 0) { $transparent_color = imagecolorsforindex($this->resource, $transparent_color_index); ${$transparent_color_index} = imagecolorallocate($new_resource, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']); imagefill($new_resource, 0, 0, $transparent_color_index); imagecolortransparent($new_resource, $transparent_color_index); } else { imagealphablending($new_resource, false); $color = imagecolorallocatealpha($new_resource, 0, 0, 0, 127); imagefill($new_resource, 0, 0, $color); imagesavealpha($new_resource, true); } break; default: $new_resource = imagecreatetruecolor($new_width, $new_height); break; } // switch imagecopyresampled($new_resource, $this->resource, 0, 0, 0, 0, $new_width, $new_height, $this->getWidth(), $this->getHeight()); if ($mutate) { imagedestroy($this->resource); $this->resource = $new_resource; $this->width = $new_width; $this->height = $new_height; return true; } else { $new_image = new SimpleGdImage(); $new_image->createFromResource($new_resource); return $new_image; } // if }
/** * Resize to $width x $height but keep the image proportion * * @param integer $width Max width * @param integer $height Max height * @param string $boundary Limit the scale action: drecrease or increase * only. If $boundary is NULL than don't limit * @param boolean $mutate Save the transformation in internal resource or * create new image and keep internal as is? * @return SimpleGdImage */ function scale($width, $height, $boundary = null, $mutate = true) { if (!is_resource($this->resource) || get_resource_type($this->resource) != 'gd') { return false; } $width = (int) $width > 0 ? (int) $width : 1; $height = (int) $height > 0 ? (int) $height : 1; $scale = min($width / $this->getWidth(), $height / $this->getHeight()); if ($boundary == self::BOUNDARY_DECREASE_ONLY) { if ($scale > 1) { if ($mutate) { return; } else { $new_image = new SimpleGdImage(); $new_image->createFromResource($this->resource); return $new_image; } // if } // if } elseif ($boundary == self::BOUNDARY_INCREASE_ONLY) { if ($scale < 1) { if ($mutate) { return; } else { $new_image = new SimpleGdImage(); $new_image->createFromResource($this->resource); return $new_image; } // if } // if } // if $new_width = floor($scale * $this->getWidth()); $new_height = floor($scale * $this->getHeight()); if ($this->getImageType() == IMAGETYPE_GIF) { $new_resource = imagecreate($new_width, $new_height); } else { $new_resource = imagecreatetruecolor($new_width, $new_height); } // if imagecopyresampled($new_resource, $this->resource, 0, 0, 0, 0, $new_width, $new_height, $this->getWidth(), $this->getHeight()); if ($mutate) { imagedestroy($this->resource); $this->resource = $new_resource; $this->width = $new_width; $this->height = $new_height; return true; } else { $new_image = new SimpleGdImage(); $new_image->createFromResource($new_resource); return $new_image; } // if }