无法裁剪和调整图像大小 [英] Trouble cropping and resizing image

查看:138
本文介绍了无法裁剪和调整图像大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为较大的图像创建缩略图。我正在使用 Jcrop 来获取农作物的坐标,但是我无法打开它裁剪成正确的缩略图图像。我已经正确设置了Jcrop,它正在通过xy坐标与盒子的大小一起发送,但是我不知道如何从中裁剪。

I'm trying to create a thumbnail image for a larger image. I'm using Jcrop to get the co-ordinates of the crop but I can't turn this into a properly cropped thumbnail image. I've set up Jcrop properly and it's sending through x-y co-ordinates along with the size of the box but I can't work out how to crop from that.

我所拥有的是服务器上图像的路径,以及4个坐标以及它们创建的正方形框的宽度和高度(我希望将正方形缩略图的纵横比锁定为1:1)。然后,我通过Ajax将其发送到我的PHP裁剪脚本,但是我无法使其根据设置的内容进行裁剪。

What I have is the path to an image on my server, along with 4 co-ordinates and the width and height of the square box they create (I've locked the aspect ratio to 1:1 as I want square thumbnails). I then send this via Ajax to my PHP cropping script, but I cannot get it to crop the based on what is set.

这是我到目前为止的内容:

This is what I have so far:

public function Crop($file, $crop) {

    $height = $width = 180;
    $ratio = $width / $height;
    $pos = strrpos($file, '.');
    $name = substr($file, 0, $pos);
    $ext = strtolower(substr($file, $pos));

    if( ! in_array($ext, array('.gif', '.jpg', '.jpeg', '.png'))) {
        return 'INVALID_EXT';
    }

    // When loading the image we check to see if the first character in file is a slash, and if so remove it as the last character of root is a slash.
    $src = ROOT . (in_array(substr($file, 0, 1), array('/', '\\')) ? substr($file, 1) : $file);
    $srcRes = imagecreatefromstring(file_get_contents($src));
    if( ! $srcRes) {
        return 'INVALID_FILE';
    }
    $srcWidth = imagesx($srcRes);
    $srcHeight = imagesy($srcRes);
    $srcRatio = $srcWidth / $srcHeight;
    $dstRes = imagecreatetruecolor($crop['w'], $crop['h']);

    if($ext == '.gif') {
        $dstBg = imagecolorallocate($dstRes, 0, 0, 0);
        imagecolortransparent($dstRes, $dstBg);
    } elseif($ext == '.png') {
        $dstBg = imagecolorallocate($dstRes, 0, 0, 0);
        imagecolortransparent($dstRes, $dstBg);
        imagealphablending($dstRes, FALSE);
        imagesavealpha($dstRes, TRUE);
    }

    $srcX = 0;
    $srcY = 0;
    if($srcRatio > $ratio) {
        $tmpWidth = $srcHeight * $ratio;
        $tmpHeight = $srcHeight;
        $srcX = ($srcWidth - $tmpWidth) / 2;
        $srcY = 0;
    } else {
        $tmpWidth = $srcWidth;
        $tmpHeight = $srcWidth / $ratio;
        $srcX = 0;
        $srcY = ($srcHeight - $tmpHeight) / 2;
    }

    imagecopyresampled($dstRes, $srcRes, 0, 0, $crop['x'], $crop['y'], $crop['w'], $crop['h'], $tmpWidth, $tmpHeight);

    $dst = ROOT . (in_array(substr($name, 0, 1), array('/', '\\')) ? substr($name, 1) : $name) . '-thumb' . $ext;
    if($ext == '.gif') {
        $try = imagegif($dstRes, $dst);
    } elseif($ext == '.jpg' || $ext == '.jpeg') {
        $try = imagejpeg($dstRes, $dst, 80);
    } elseif($ext == '.png') {
        $try = imagepng($newThumbImageResource, $dst);
    }

    if( ! $try) {
        return 'CREATE_ERR';
    }

    return 'SUCCESS';

}

我尝试更改<$中的所有内容c $ c> imagecopy重新采样,但无法按照Jcrop发送的内容进行裁剪。如果我使用 $ srcWidth $ srcHeight ,它将保持原始图像的长宽比并将其压缩为180px的正方形。

I've tried changing all sorts of things in imagecopyresampled but cannot get it to crop as per what Jcrop is sending through. If I use $srcWidth and $srcHeight it maintains the aspect ratio of the original image and squishes it into the 180px square. But it doesn't seem to be resizing it or cropping it from the right place.

有人可以帮我弄清楚我应该在哪里使用什么数字吗?我整天都在撞我的头。



编辑

Can someone please help me work out what figures I should be using where? I've been banging my head against this all day.


EDIT

这是其余的代码。首先,运行JCrop的JavaScript。在上载Ajax文件以创建该图像的缩略图后触发:

Here is the rest of the code. First the JavaScript that runs JCrop. It's triggered after an Ajax file upload to create a thumbnail of that image:

这是Ajax函数上载,最后将其称为裁剪器。

This is the Ajax function upload that at the end calls the cropper.

$(function () {

    'use strict';
    // Change this to the location of your server-side upload handler:
    var url = '/eshop/library/ajax/ajax.file-upload.php';
    var uploadDir = 'prodimages/';

    $('.listing-image').fileupload({
        url: url,
        dataType: 'json',
        autoUpload: true,
        acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
        maxFileSize: 1000000, // 1 MB
        // Enable image resizing, except for Android and Opera,
        // which actually support image resizing, but fail to
        // send Blob objects via XHR requests:
        disableImageResize: /Android(?!.*Chrome)|Opera/
            .test(window.navigator.userAgent),
        previewMaxWidth: 120,
        previewMaxHeight: 120,
        previewCrop: true,
        paramName: 'files[]',
        formData: {uploadDir: uploadDir}
    })/*.on('fileuploadprocessalways', function (e, data) {
        var index = data.index;
        var file = data.files[index];
        $(this).html(file.preview);
    })*/.on('fileuploadprogressall', function (e, data) {
        var progress = parseInt(data.loaded / data.total * 100, 10);
        $('.listing-progress', this).css(
            'width',
            progress + '%'
        );
    }).on('fileuploaddone', function (e, data) {
        var file = data.result.files[0];
        var html = '<div class="listing-preview">\
            <img src="' + file.thumbnailUrl + '" data-name="' + file.name + '">\
            <div class="listing-preview-delete">Delete</div>\
        </div>';
        $(this).html(html).data('delete-url', file.deleteUrl).css('padding', 0);

        Crop('/' + uploadDir + file.name, $(this).prop('id'));

    });

});

这会将作物详细信息通过Ajax发送到上面的PHP脚本中。

This sends the crop details through to the PHP script above via Ajax.

$(document).on('click', '.crop-btn', function() {

    var data = {
        file: $(this).data('src'),
        crop: jcrop.tellSelect()
    }
    ShowLoadingById('crop-loading');
    AjaxHandler('/eshop/library/ajax/ajax.product-crop-thumb.php', data, 'POST', true);

});

裁剪窗口是一个灯箱,此功能将其垂直居中,并在垂直方向大于图像时调整图像大小

The crop window is a lightbox, this function vertically centres it and resizes the image if it's vertically bigger than the available space.

function CentreCrop() {

    var m = ($(window).height() - ($('.crop > div').height() + 60)) / 2;
    $('.crop > div').css('margin-top', m);

    if($('#crop-img').height() > $('.crop > div').height() - 30) {
        $('#crop-img-container').height($('.crop > div').height() - 30);
    }

}

这是存储的初始函数

var toBeCropped = [];
var working = false;
function Crop(file, id) {

    toBeCropped.push({path: file, id: id});

    if( ! working) {
        working = true;
        CropWorker();
    }

}

这是我在作物已完成销毁jcrop并清除作物灯箱,以准备下一个图像进行裁剪。

This is the function I run when the crop has finished to destroy jcrop and clear the crop lightbox ready for the next image to be cropped.

function CropSuccess() {

    $('.crop').fadeOut(250, function() {

        jcrop.destroy();
        $(this).html('');
        CropWorker();

    });

}

这是在灯箱中实际创建内容的工作人员并启动jcrop。

This is the worker that actually creates the content in the lightbox and initiates jcrop.

function CropWorker() {

    if(toBeCropped.length > 0) {
        file = toBeCropped.shift();
        html = '<div>\
            <div id="crop-img-container" class="row-fluid">\
                <img id="crop-img" src="' + file.path + '">\
            </div>\
            <div class="row-fluid">\
                <div class="span3 offset9">\
                    <button class="span12 btn crop-btn" data-id="' + file.id + '" data-src="' + file.path + '">Create Thumb</button>\
                </div>\
            </div>\
            <div class="row-fluid loading-screen" id="crop-loading">\
                <div>\
                    <h4>Cropping...</h4>\
                    <img src="/img/loading.gif">\
                </div>\
            </div>\
        </div>';
        $('.crop').html(html);
        $('.crop').fadeIn(250);
        $('#crop-img').load(function() {
            CentreCrop();
            $('#crop-img').Jcrop({
                aspectRatio: 1/1,
                bgColor: 'black',
                bgOpacity: 0.4,
                boxWidth: $('#crop-img').width(), // Only just recently added boxWidth and height to see if that would fix it, no difference with or without.
                boxHeight: $('#crop-img').height(),
                //maxSize: [300,300],
                minSize: [180,180]
            }, function() {
                jcrop = this;
                jcrop.setSelect([0,0,180,180]);
            });
        });
    } else {
        working = false;
    }

}






更新

部分问题似乎是图像调整大小。我正在更改图像大小以适合屏幕,尽管JCrop会帮我解决这个问题,但是似乎您必须告诉JCrop图像的原始尺寸。在初始化JCrop时,我已经添加了true size选项,看来我们已经快到了。

Part of the problem it seems was the image resizing. I was changing the image size to fit the screen, I though JCrop would take care of that for me but it seems you have to tell JCrop the original dimensions of the image. I've added the true size option when initializing JCrop and it seems we're almost there.

对于较小的图像,那些小于1000像素的裁剪器效果很好。但是对于较大的像素(1000像素以上),它会产生黑色图像。当我将其与JCrop演示脚本一起使用时,它不会执行此操作,但是两者之间的唯一区别是,一个是将文件输出到屏幕上,另一个是保存文件。我看不到任何其他差异,也无法弄清楚为什么会发生这种情况。

For smaller images, those under 1000px the cropper seems to be working great. But for larger ones (1000px +) it's producing black images. It doesn't do this when I use it with the JCrop demo script but the only difference between the two is one is outputting the file to the screen and the other is saving it. I can't see any other difference or figure out why this would happen.

UPDATE 2
似乎只受影响了如果我正在通过Ajax运行代码。如果我运行完全相同的功能而只是发布到页面上并在顶部运行它,则无论原始图像的大小还是我绘制的框的大小,缩略图每次都能完美创建。

UPDATE 2 It seems to only be affected if I'm running the code through Ajax. If I run the exact same function just posting to a page and running it at the top, the thumbnail is created perfectly every time, no matter what the size of the original image or the size of the box I draw.

推荐答案

在您的代码中 $ crop ['w'] $ crop ['h'] 是源;

In your code $crop['w'] and $crop['h'] are for the source;

$ tmpWidth $ tmpHeight 用于目的地;

所以您应该根据 imagecopyresampled 函数( http://php.net//manual/fr /function.imagecopyresampled.php )。

so you should switch them according to imagecopyresampled function (http://php.net//manual/fr/function.imagecopyresampled.php).

imagecopyresampled($dstRes, $srcRes, 0, 0, $crop['x'], $crop['y'], $tmpWidth, $tmpHeight, $crop['w'], $crop['h']);






编辑2

不应为目标图像设置 $ crop 数据,而应使用所需大小:

Your destination image shouldn't be set with $crop data, but with the size you want :

$dstRes = imagecreatetruecolor(180, 180);

而且我不确定 $ tmpWidth 的值是多少code>和 $ tmpHeight ,但它们都应为180,因为这是您想要的大小:

And i'm not sure what value you have from $tmpWidth and $tmpHeight but they should be both 180 since it's the size you want :

imagecopyresampled($dstRes, $srcRes, 0, 0, $crop['x'], $crop['y'], 180, 180, $crop['w'], $crop['h']);






编辑3

好,最后一次尝试,我有一个jcrop的工作代码,但是我没有在函数中使用它,它仍然以相同的方式工作。我逐行检查了您的代码,这就是我所拥有的。我删除了有关比率的所有内容,由Jcrop管理,无需使用PHP。正确的目标图像,正确的 imagecopyresampled ,对我来说看起来不错:/

Ok last try, i've a working code for jcrop but i don't use it inside a function, it's still working the same way. I checked line by line your code and here is what i have. I removed everything about ratio, Jcrop manage it, no need to do it with PHP. Proper dest image, proper imagecopyresampled, looks good to me :/

public function Crop($file, $crop) {

    $height = $width = 180;

    // your file type checking
    $pos = strrpos($file, '.');
    $name = substr($file, 0, $pos);
    $ext = strtolower(substr($file, $pos));

    if( ! in_array($ext, array('.gif', '.jpg', '.jpeg', '.png'))) {
        return 'INVALID_EXT';
    }

    // source image
    $src = ROOT . (in_array(substr($file, 0, 1), array('/', '\\')) ? substr($file, 1) : $file);
    $srcRes = imagecreatefromstring(file_get_contents($src));
    if( ! $srcRes) {
        return 'INVALID_FILE';
    }

    // destination image
    $dstRes = imagecreatetruecolor($width, $height);

    // file type transparence
    if($ext == '.gif') {
        $dstBg = imagecolorallocate($dstRes, 0, 0, 0);
        imagecolortransparent($dstRes, $dstBg);
    } elseif($ext == '.png') {
        $dstBg = imagecolorallocate($dstRes, 0, 0, 0);
        imagecolortransparent($dstRes, $dstBg);
        imagealphablending($dstRes, FALSE);
        imagesavealpha($dstRes, TRUE);
    }

    // bool imagecopyresampled ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )
    imagecopyresampled($dstRes, $srcRes, 0, 0, $crop['x'], $crop['y'], $width, $height, $crop['w'], $crop['h']);

    $dst = ROOT . (in_array(substr($name, 0, 1), array('/', '\\')) ? substr($name, 1) : $name) . '-thumb' . $ext;
    if($ext == '.gif') {
        $try = imagegif($dstRes, $dst);
    } elseif($ext == '.jpg' || $ext == '.jpeg') {
        $try = imagejpeg($dstRes, $dst, 80);
    } elseif($ext == '.png') {
        $try = imagepng($newThumbImageResource, $dst);
    }

    if( ! $try) {
        return 'CREATE_ERR';
    }

    return 'SUCCESS';

}

这篇关于无法裁剪和调整图像大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆