在Magento 1.7.0.2中实现了Imagemagick而不是GD2,如下所示:
http://www.magentocommerce.com/boards/v/viewthread/6158/P135/#t328638
然而,新图像不成比例,导致拉伸。他们对GD2非常完美
说明:
在Gd2.php文件中,在save()函数中注释掉
call_user_func_array($this->_getCallback('output'), $functionParameters);
这是Magento调用imagejpeg()函数的地方。呸。
现在在注释掉的行下方添加以下代码。
$source_file = $this->_fileSrcPath.'/'.$this->_fileSrcName;
$image_info = getimagesize($source_file);
$im = new Imagick();
$im->readImage($source_file);
//check to see if image needs to be resized (eg. thumbnails)
if ($image_info[0] != $this->_imageSrcWidth) {
$im->thumbnailImage($this->_imageSrcWidth, $this->_imageSrcHeight);
}
$im->writeImage($fileName);
这是实施的代码
<?php
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@magentocommerce.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magentocommerce.com for more information.
*
* @category Varien
* @package Varien_Image
* @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
class Varien_Image_Adapter_Gd2 extends Varien_Image_Adapter_Abstract
{
protected $_requiredExtensions = Array("gd");
private static $_callbacks = array(
IMAGETYPE_GIF => array('output' => 'imagegif', 'create' => 'imagecreatefromgif'),
IMAGETYPE_JPEG => array('output' => 'imagejpeg', 'create' => 'imagecreatefromjpeg'),
IMAGETYPE_PNG => array('output' => 'imagepng', 'create' => 'imagecreatefrompng'),
IMAGETYPE_XBM => array('output' => 'imagexbm', 'create' => 'imagecreatefromxbm'),
IMAGETYPE_WBMP => array('output' => 'imagewbmp', 'create' => 'imagecreatefromxbm'),
);
/**
* Whether image was resized or not
*
* @var bool
*/
protected $_resized = false;
public function open($filename)
{
$this->_fileName = $filename;
$this->getMimeType();
$this->_getFileAttributes();
$this->_imageHandler = call_user_func($this->_getCallback('create'), $this->_fileName);
}
public function save($destination=null, $newName=null)
{
$fileName = ( !isset($destination) ) ? $this->_fileName : $destination;
if( isset($destination) && isset($newName) ) {
$fileName = $destination . "/" . $newName;
} elseif( isset($destination) && !isset($newName) ) {
$info = pathinfo($destination);
$fileName = $destination;
$destination = $info['dirname'];
} elseif( !isset($destination) && isset($newName) ) {
$fileName = $this->_fileSrcPath . "/" . $newName;
} else {
$fileName = $this->_fileSrcPath . $this->_fileSrcName;
}
$destinationDir = ( isset($destination) ) ? $destination : $this->_fileSrcPath;
if( !is_writable($destinationDir) ) {
try {
$io = new Varien_Io_File();
$io->mkdir($destination);
} catch (Exception $e) {
throw new Exception("Unable to write file into directory '{$destinationDir}'. Access forbidden.");
}
}
if (!$this->_resized) {
// keep alpha transparency
$isAlpha = false;
$isTrueColor = false;
$this->_getTransparency($this->_imageHandler, $this->_fileType, $isAlpha, $isTrueColor);
if ($isAlpha) {
if ($isTrueColor) {
$newImage = imagecreatetruecolor($this->_imageSrcWidth, $this->_imageSrcHeight);
} else {
$newImage = imagecreate($this->_imageSrcWidth, $this->_imageSrcHeight);
}
$this->_fillBackgroundColor($newImage);
imagecopy(
$newImage,
$this->_imageHandler,
0, 0,
0, 0,
$this->_imageSrcWidth, $this->_imageSrcHeight
);
$this->_imageHandler = $newImage;
}
}
$functionParameters = array();
$functionParameters[] = $this->_imageHandler;
$functionParameters[] = $fileName;
// set quality param for JPG file type
if (!is_null($this->quality()) && $this->_fileType == IMAGETYPE_JPEG)
{
$functionParameters[] = $this->quality();
}
// set quality param for PNG file type
if (!is_null($this->quality()) && $this->_fileType == IMAGETYPE_PNG)
{
$quality = round(($this->quality() / 100) * 10);
if ($quality < 1) {
$quality = 1;
} elseif ($quality > 10) {
$quality = 10;
}
$quality = 10 - $quality;
$functionParameters[] = $quality;
}
//call_user_func_array($this->_getCallback('output'), $functionParameters);
$source_file = $this->_fileSrcPath.'/'.$this->_fileSrcName;
$image_info = getimagesize($source_file);
$im = new Imagick();
$im->readImage($source_file);
//check to see if image needs to be resized (eg. thumbnails)
if ($image_info[0] != $this->_imageSrcWidth) {
$im->thumbnailImage($this->_imageSrcWidth, $this->_imageSrcHeight);
}
$im->writeImage($fileName);
}
public function display()
{
header("Content-type: ".$this->getMimeType());
call_user_func($this->_getCallback('output'), $this->_imageHandler);
}
/**
* Obtain function name, basing on image type and callback type
*
* @param string $callbackType
* @param int $fileType
* @return string
* @throws Exception
*/
private function _getCallback($callbackType, $fileType = null, $unsupportedText = 'Unsupported image format.')
{
if (null === $fileType) {
$fileType = $this->_fileType;
}
if (empty(self::$_callbacks[$fileType])) {
throw new Exception($unsupportedText);
}
if (empty(self::$_callbacks[$fileType][$callbackType])) {
throw new Exception('Callback not found.');
}
return self::$_callbacks[$fileType][$callbackType];
}
private function _fillBackgroundColor(&$imageResourceTo)
{
// try to keep transparency, if any
if ($this->_keepTransparency) {
$isAlpha = false;
$transparentIndex = $this->_getTransparency($this->_imageHandler, $this->_fileType, $isAlpha);
try {
// fill truecolor png with alpha transparency
if ($isAlpha) {
if (!imagealphablending($imageResourceTo, false)) {
throw new Exception('Failed to set alpha blending for PNG image.');
}
$transparentAlphaColor = imagecolorallocatealpha($imageResourceTo, 0, 0, 0, 127);
if (false === $transparentAlphaColor) {
throw new Exception('Failed to allocate alpha transparency for PNG image.');
}
if (!imagefill($imageResourceTo, 0, 0, $transparentAlphaColor)) {
throw new Exception('Failed to fill PNG image with alpha transparency.');
}
if (!imagesavealpha($imageResourceTo, true)) {
throw new Exception('Failed to save alpha transparency into PNG image.');
}
return $transparentAlphaColor;
}
// fill image with indexed non-alpha transparency
elseif (false !== $transparentIndex) {
$transparentColor = false;
if ($transparentIndex >=0 && $transparentIndex <= imagecolorstotal($this->_imageHandler)) {
list($r, $g, $b) = array_values(imagecolorsforindex($this->_imageHandler, $transparentIndex));
$transparentColor = imagecolorallocate($imageResourceTo, $r, $g, $b);
}
if (false === $transparentColor) {
throw new Exception('Failed to allocate transparent color for image.');
}
if (!imagefill($imageResourceTo, 0, 0, $transparentColor)) {
throw new Exception('Failed to fill image with transparency.');
}
imagecolortransparent($imageResourceTo, $transparentColor);
return $transparentColor;
}
}
catch (Exception $e) {
// fallback to default background color
}
}
list($r, $g, $b) = $this->_backgroundColor;
$color = imagecolorallocate($imageResourceTo, $r, $g, $b);
if (!imagefill($imageResourceTo, 0, 0, $color)) {
throw new Exception("Failed to fill image background with color {$r} {$g} {$b}.");
}
return $color;
}
/**
* Gives true for a PNG with alpha, false otherwise
*
* @param string $fileName
* @return boolean
*/
public function checkAlpha($fileName)
{
return ((ord(file_get_contents($fileName, false, null, 25, 1)) & 6) & 4) == 4;
}
private function _getTransparency($imageResource, $fileType, &$isAlpha = false, &$isTrueColor = false)
{
$isAlpha = false;
$isTrueColor = false;
// assume that transparency is supported by gif/png only
if ((IMAGETYPE_GIF === $fileType) || (IMAGETYPE_PNG === $fileType)) {
// check for specific transparent color
$transparentIndex = imagecolortransparent($imageResource);
if ($transparentIndex >= 0) {
return $transparentIndex;
}
// assume that truecolor PNG has transparency
elseif (IMAGETYPE_PNG === $fileType) {
$isAlpha = $this->checkAlpha($this->_fileName);
$isTrueColor = true;
return $transparentIndex; // -1
}
}
if (IMAGETYPE_JPEG === $fileType) {
$isTrueColor = true;
}
return false;
}
/**
* Change the image size
*
* @param int $frameWidth
* @param int $frameHeight
*/
public function resize($frameWidth = null, $frameHeight = null)
{
if (empty($frameWidth) && empty($frameHeight)) {
throw new Exception('Invalid image dimensions.');
}
// calculate lacking dimension
if (!$this->_keepFrame) {
if (null === $frameWidth) {
$frameWidth = round($frameHeight * ($this->_imageSrcWidth / $this->_imageSrcHeight));
}
elseif (null === $frameHeight) {
$frameHeight = round($frameWidth * ($this->_imageSrcHeight / $this->_imageSrcWidth));
}
}
else {
if (null === $frameWidth) {
$frameWidth = $frameHeight;
}
elseif (null === $frameHeight) {
$frameHeight = $frameWidth;
}
}
// define coordinates of image inside new frame
$srcX = 0;
$srcY = 0;
$dstX = 0;
$dstY = 0;
$dstWidth = $frameWidth;
$dstHeight = $frameHeight;
if ($this->_keepAspectRatio) {
// do not make picture bigger, than it is, if required
if ($this->_constrainOnly) {
if (($frameWidth >= $this->_imageSrcWidth) && ($frameHeight >= $this->_imageSrcHeight)) {
$dstWidth = $this->_imageSrcWidth;
$dstHeight = $this->_imageSrcHeight;
}
}
// keep aspect ratio
if ($this->_imageSrcWidth / $this->_imageSrcHeight >= $frameWidth / $frameHeight) {
$dstHeight = round(($dstWidth / $this->_imageSrcWidth) * $this->_imageSrcHeight);
} else {
$dstWidth = round(($dstHeight / $this->_imageSrcHeight) * $this->_imageSrcWidth);
}
}
// define position in center (TODO: add positions option)
$dstY = round(($frameHeight - $dstHeight) / 2);
$dstX = round(($frameWidth - $dstWidth) / 2);
// get rid of frame (fallback to zero position coordinates)
if (!$this->_keepFrame) {
$frameWidth = $dstWidth;
$frameHeight = $dstHeight;
$dstY = 0;
$dstX = 0;
}
// create new image
$isAlpha = false;
$isTrueColor = false;
$this->_getTransparency($this->_imageHandler, $this->_fileType, $isAlpha, $isTrueColor);
if ($isTrueColor) {
$newImage = imagecreatetruecolor($frameWidth, $frameHeight);
}
else {
$newImage = imagecreate($frameWidth, $frameHeight);
}
// fill new image with required color
$this->_fillBackgroundColor($newImage);
// resample source image and copy it into new frame
imagecopyresampled(
$newImage,
$this->_imageHandler,
$dstX, $dstY,
$srcX, $srcY,
$dstWidth, $dstHeight,
$this->_imageSrcWidth, $this->_imageSrcHeight
);
$this->_imageHandler = $newImage;
$this->refreshImageDimensions();
$this->_resized = true;
}
public function rotate($angle)
{
/*
$isAlpha = false;
$backgroundColor = $this->_getTransparency($this->_imageHandler, $this->_fileType, $isAlpha);
list($r, $g, $b) = $this->_backgroundColor;
if ($isAlpha) {
$backgroundColor = imagecolorallocatealpha($this->_imageHandler, 0, 0, 0, 127);
}
elseif (false === $backgroundColor) {
$backgroundColor = imagecolorallocate($this->_imageHandler, $r, $g, $b);
}
$this->_imageHandler = imagerotate($this->_imageHandler, $angle, $backgroundColor);
//*/
$this->_imageHandler = imagerotate($this->_imageHandler, $angle, $this->imageBackgroundColor);
$this->refreshImageDimensions();
}
public function watermark($watermarkImage, $positionX=0, $positionY=0, $watermarkImageOpacity=30, $repeat=false)
{
list($watermarkSrcWidth, $watermarkSrcHeight, $watermarkFileType, ) = getimagesize($watermarkImage);
$this->_getFileAttributes();
$watermark = call_user_func($this->_getCallback(
'create',
$watermarkFileType,
'Unsupported watermark image format.'
), $watermarkImage);
$merged = false;
if ($this->getWatermarkWidth() &&
$this->getWatermarkHeigth() &&
($this->getWatermarkPosition() != self::POSITION_STRETCH)
) {
$newWatermark = imagecreatetruecolor($this->getWatermarkWidth(), $this->getWatermarkHeigth());
imagealphablending($newWatermark, false);
$col = imagecolorallocate($newWatermark, 255, 255, 255);
imagecolortransparent($newWatermark, $col);
imagefilledrectangle($newWatermark, 0, 0, $this->getWatermarkWidth(), $this->getWatermarkHeigth(), $col);
imagealphablending($newWatermark, true);
imageSaveAlpha($newWatermark, true);
imagecopyresampled(
$newWatermark,
$watermark,
0, 0, 0, 0,
$this->getWatermarkWidth(), $this->getWatermarkHeigth(),
imagesx($watermark), imagesy($watermark)
);
$watermark = $newWatermark;
}
if( $this->getWatermarkPosition() == self::POSITION_TILE ) {
$repeat = true;
} elseif( $this->getWatermarkPosition() == self::POSITION_STRETCH ) {
$newWatermark = imagecreatetruecolor($this->_imageSrcWidth, $this->_imageSrcHeight);
imagealphablending($newWatermark, false);
$col = imagecolorallocate($newWatermark, 255, 255, 255);
imagecolortransparent($newWatermark, $col);
imagefilledrectangle($newWatermark, 0, 0, $this->_imageSrcWidth, $this->_imageSrcHeight, $col);
imagealphablending($newWatermark, true);
imageSaveAlpha($newWatermark, true);
imagecopyresampled(
$newWatermark,
$watermark,
0, 0, 0, 0,
$this->_imageSrcWidth, $this->_imageSrcHeight,
imagesx($watermark), imagesy($watermark)
);
$watermark = $newWatermark;
} elseif( $this->getWatermarkPosition() == self::POSITION_CENTER ) {
$positionX = ($this->_imageSrcWidth/2 - imagesx($watermark)/2);
$positionY = ($this->_imageSrcHeight/2 - imagesy($watermark)/2);
imagecopymerge(
$this->_imageHandler,
$watermark,
$positionX, $positionY,
0, 0,
imagesx($watermark), imagesy($watermark),
$this->getWatermarkImageOpacity()
);
} elseif( $this->getWatermarkPosition() == self::POSITION_TOP_RIGHT ) {
$positionX = ($this->_imageSrcWidth - imagesx($watermark));
imagecopymerge(
$this->_imageHandler,
$watermark,
$positionX, $positionY,
0, 0,
imagesx($watermark), imagesy($watermark),
$this->getWatermarkImageOpacity()
);
} elseif( $this->getWatermarkPosition() == self::POSITION_TOP_LEFT ) {
imagecopymerge(
$this->_imageHandler,
$watermark,
$positionX, $positionY,
0, 0,
imagesx($watermark), imagesy($watermark),
$this->getWatermarkImageOpacity()
);
} elseif( $this->getWatermarkPosition() == self::POSITION_BOTTOM_RIGHT ) {
$positionX = ($this->_imageSrcWidth - imagesx($watermark));
$positionY = ($this->_imageSrcHeight - imagesy($watermark));
imagecopymerge(
$this->_imageHandler,
$watermark,
$positionX, $positionY,
0, 0,
imagesx($watermark), imagesy($watermark),
$this->getWatermarkImageOpacity()
);
} elseif( $this->getWatermarkPosition() == self::POSITION_BOTTOM_LEFT ) {
$positionY = ($this->_imageSrcHeight - imagesy($watermark));
imagecopymerge(
$this->_imageHandler,
$watermark,
$positionX, $positionY,
0, 0,
imagesx($watermark), imagesy($watermark),
$this->getWatermarkImageOpacity()
);
}
if( $repeat === false && $merged === false ) {
imagecopymerge(
$this->_imageHandler,
$watermark,
$positionX, $positionY,
0, 0,
imagesx($watermark), imagesy($watermark),
$this->getWatermarkImageOpacity()
);
} else {
$offsetX = $positionX;
$offsetY = $positionY;
while( $offsetY <= ($this->_imageSrcHeight+imagesy($watermark)) ) {
while( $offsetX <= ($this->_imageSrcWidth+imagesx($watermark)) ) {
imagecopymerge(
$this->_imageHandler,
$watermark,
$offsetX, $offsetY,
0, 0,
imagesx($watermark), imagesy($watermark),
$this->getWatermarkImageOpacity()
);
$offsetX += imagesx($watermark);
}
$offsetX = $positionX;
$offsetY += imagesy($watermark);
}
}
imagedestroy($watermark);
$this->refreshImageDimensions();
}
public function crop($top=0, $left=0, $right=0, $bottom=0)
{
if( $left == 0 && $top == 0 && $right == 0 && $bottom == 0 ) {
return;
}
$newWidth = $this->_imageSrcWidth - $left - $right;
$newHeight = $this->_imageSrcHeight - $top - $bottom;
$canvas = imagecreatetruecolor($newWidth, $newHeight);
if ($this->_fileType == IMAGETYPE_PNG) {
$this->_saveAlpha($canvas);
}
imagecopyresampled(
$canvas,
$this->_imageHandler,
0, 0, $left, $top,
$newWidth, $newHeight,
$newWidth, $newHeight
);
$this->_imageHandler = $canvas;
$this->refreshImageDimensions();
}
public function checkDependencies()
{
foreach( $this->_requiredExtensions as $value ) {
if( !extension_loaded($value) ) {
throw new Exception("Required PHP extension '{$value}' was not loaded.");
}
}
}
private function refreshImageDimensions()
{
$this->_imageSrcWidth = imagesx($this->_imageHandler);
$this->_imageSrcHeight = imagesy($this->_imageHandler);
}
function __destruct()
{
@imagedestroy($this->_imageHandler);
}
/*
* Fixes saving PNG alpha channel
*/
private function _saveAlpha($imageHandler)
{
$background = imagecolorallocate($imageHandler, 0, 0, 0);
ImageColorTransparent($imageHandler, $background);
imagealphablending($imageHandler, false);
imagesavealpha($imageHandler, true);
}
}
答案 0 :(得分:0)
您是否尝试过hackathon magento imagemagick enabler?
[https://github.com/magento-hackathon/Perfect_Watermarks][1]
我将在一分钟内对此进行测试,因此此建议目前绝对未经测试。