CodeIgniter调整大小和按轴裁剪

4

我在CodeIgniter项目中使用了一个图片裁剪器,它可以像picresize.com(我使用jCrop)一样裁剪图片。下面是原始代码:

<?php
$save_to = $this->config->item('images_gallery_thumb_folder').$data['photo_image'];

$targ_w = $this->config->item('gallery_thumb_width');
$targ_h = $this->config->item('gallery_thumb_height');
$src = $this->config->item('images_gallery_folder').$data['photo_image'];

$types = array(1 => 'gif', 'jpeg', 'png');
list($width,$height,$type) = getimagesize($src);

switch ($types[$type]) {
    case 'jpeg':
        $img_r = imagecreatefromjpeg($src);
        break;
    case 'gif':
        $img_r = imagecreatefromgif($src);
        break;

    case 'png':
        $img_r = imagecreatefrompng($src);
        break;

    default:
        $img_r = imagecreatefromjpeg($src);
        break;
}

$dst_r = ImageCreateTrueColor($targ_w,$targ_h );

imagecopyresampled($dst_r,$img_r,0,0,$_POST['x'],$_POST['y'],
    $targ_w,$targ_h,$_POST['w'],$_POST['h']);


switch ($types[$type]) {
    case 'jpeg':
        imagejpeg($dst_r, $save_to, 90); //90 = jpeg quality
        break;
    case 'gif':
        imagegif($dst_r, $save_to);
        break;
    case 'png':
        imagepng($dst_r, $save_to);
        break;
    default:
        imagejpeg($dst_r, $save_to, 90); //90 = jpeg quality
        break;
}


imagedestroy($dst_r);
?>

但我希望按照CodeIgniter的方式来处理这个问题。

到目前为止,这是我想出的方案:

<?php
$img_config = array(
    'source_image'      => $src,
    'new_image'         => $save_to,
    'maintain_ratio'    => false,
    'width'             => $targ_w,
    'height'            => $targ_h,
    'x_axis'            => $_POST['x'],
    'y_axis'            => $_POST['y']
);

$this->load->library('image_lib',$img_config);
//$this->image_lib->resize();
$this->image_lib->crop();
?>

事实上,它从位置进行裁剪,但不会调整大小(类似于我设置了一个更大的裁剪正方形)。它只从给定的位置进行裁剪。
我在项目中还使用image_moo库,但我也无法成功。 编辑: 在Image_moo中,这是我到目前为止想出的代码:
$this->image_moo
                ->load($src)
                ->crop($_POST['x'],$_POST['y'],($_POST['x']+$_POST['w']),($_POST['y']+$_POST['h']))
                ->resize($targ_w,$targ_h)
                ->save($save_to,true);

问题在于,当我使用resize参数时,它完全忽略了裁剪线并调整整个图像的大小。如果我先调整大小再调用裁剪,它就会失败。我可以通过使用两个image_moo调用来克服这个问题,但我不想这样做。
这也行不通:
$this->image_moo
                ->load($src)
                ->crop($_POST['x'],$_POST['y'],($_POST['x']+$_POST['w']),($_POST['y']+$_POST['h']))
                //->resize($targ_w,$targ_h)
                ->save($save_to,true)
                ->resize($targ_w,$targ_h)
                ->save($save_to,true);

例如:这样它就能工作:
$this->image_moo
                ->load($src)
                ->crop($_POST['x'],$_POST['y'],($_POST['x']+$_POST['w']),($_POST['y']+$_POST['h']))
                //->resize($targ_w,$targ_h)
                ->save($save_to,true);
            $this->image_moo
                ->load($save_to)
                ->resize($targ_w,$targ_h)
                ->save($save_to,true);

如何使用CodeIgniter(或image_moo)一次调用来进行给定x/y偏移量的缩放+裁剪?

你可能会问为什么我要担心调用两次。嗯,PQ很重要,我担心调用两次会降低图像质量。

提前致谢。


你需要先进行裁剪,以获取正确的比例,然后再进行调整大小。在 Codeigniter 中,它们被拆分成了单独的函数。 - Jeemusu
你的作物脚本是否正常工作? - Ankur Saxena
抱歉 @Arda,我完全没有注意到你提到了 Image_Moo。请参考 http://ellislab.com/forums/viewthread/161469/P90,这可能对你有所帮助。 - Gavin
@Gavin,请检查我的问题以获取示例代码编辑:我已经成功了,但是调用image_moo两次(也提供了原因)。你是否只调用了一次image_moo就解决了问题? - Arda
@Jeemusu resize_crop 首先调整尺寸,然后裁剪。所以结果不是我需要的。我需要相反的操作,类似于 crop_resize :) - Arda
显示剩余10条评论
1个回答

8
您给出的Codeigniter代码除了一个逻辑问题外都是正确的:您在同一张图片文件上进行操作并输出两次,因此最后一次更改原始文件会覆盖您的输出文件。
我认为这是CI的Image_Lib类的限制,因为每个操作都是单独完成的-没有办法一次性“调整大小和裁剪”。
您必须在每个操作之间重新初始化Image_Lib类,以确保下一个操作在上一个操作的输出文件上调用。
$img_config = array(
    'source_image'      => $src,
    'new_image'         => $save_to,
    'maintain_ratio'    => false,
    'width'             => $targ_w,
    'height'            => $targ_h,
    'x_axis'            => $_POST['x'],
    'y_axis'            => $_POST['y']
);

$this->load->library('image_lib', $img_config);
$this->image_lib->resize();

// Now change the input file to the one that just got resized
// See also $this->image_lib->clear()
$img_config['source_image'] = $save_to;
$this->image_lib->initialize($img_config); 

$this->image_lib->crop();

您也可以使用两个不同的配置数组:
$this->load->library('image_lib');

$this->image_lib->initialize(array(
    'source_image'      => $src,
    'new_image'         => $save_to,
    'maintain_ratio'    => false,
    'width'             => $targ_w,
    'height'            => $targ_h,
));
$this->image_lib->resize();

$this->image_lib->clear();

$this->image_lib->initialize(array(
    'source_image'      => $save_to,
    'x_axis'            => $_POST['x'],
    'y_axis'            => $_POST['y']
));
$this->image_lib->crop();

或者,您可以首先创建图像文件的副本,然后在每次调用图像库类时对该副本进行操作,避免重新初始化新的source_image带来的麻烦:

copy($src, $save_to);
$this->load->library('image_lib', array(
    'source_image'      => $save_to,
    'maintain_ratio'    => false,
    'width'             => $targ_w,
    'height'            => $targ_h,
    'x_axis'            => $_POST['x'],
    'y_axis'            => $_POST['y']
));
$this->image_lib->resize();
$this->image_lib->crop();

1
CI的Image_lib绝对没有一次完成它的方法。您尝试过Image_Moo中的“resize_crop”方法吗? CI库的一个重点是抽象出一些功能,以便在选择GD / GD2,NetPBM或ImageMagick时可以使用。 Image_Moo仅使用GD作为原始代码所做的那样,您可能只想使用您自己的函数来使用您似乎满意并扩展CI的Image_lib。 但是,我很惊讶您仅通过单独调用裁剪/调整大小就注意到了降低的图像质量。 - Wesley Murch
1
啊,我明白了。你使用的“vanilla”代码简短而简洁,似乎可以实现你想要的功能。为什么不直接扩展Image_lib类并将其作为新方法添加进去呢? - Wesley Murch
事实是我担心它可能无法在线工作。我将无法管理代码将上传的服务器(也许GD或GD2未安装,因此我需要重新编写该代码),因此即使我使用原始代码扩展了image_lib,我的担忧仍将继续存在。无论如何,您为我澄清了很多问题,所以我将接受您的答案,谢谢! - Arda
我会说GD或GD2很可能已经被安装了。如果确实存在问题,您可以在函数中检查其是否可用,如果不可用,则使用另一种方法(回退到Image_lib的常规裁剪/调整大小方法)。 - Wesley Murch
如果某个特定的图像库未安装,那么 image_lib 肯定是您最好的选择,因为您可以在调用相同函数的同时切换不同的库。 - Rob Grant
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接