Jcrop在处理大尺寸图片时存在问题。

5

我正在尝试用php和jquery实现一个上传表单,并且现在除了一件我认为很无聊但是还是无法理解的事情外,一切都很好。

让我来解释一下:

实际上,当我运行图片上传时,我会立即在屏幕上打印出一个临时预览,我会在这个预览中裁剪我喜欢的图像,然后保存缩略图。然而,如果我插入高分辨率的jpg,则会看到实际大小,因此对于页面来说太大了。以下是代码:

INDEX.PHP

<?php
function uploadImageFile() { // Note: GD library is required for this function
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $iWidth = $iHeight = 100; // desired image result dimensions
    $iJpgQuality = 90;

    if ($_FILES) {

        // if no errors and size less than 250kb
        if (! $_FILES['image_file']['error'] && $_FILES['image_file']['size'] < 55555250 * 1024) {
            if (is_uploaded_file($_FILES['image_file']['tmp_name'])) {

                // new unique filename
                $sTempFileName = 'cache/' . md5(time().rand());

                // move uploaded file into cache folder
                move_uploaded_file($_FILES['image_file']['tmp_name'], $sTempFileName);

                // change file permission to 644
                @chmod($sTempFileName, 0644);

                if (file_exists($sTempFileName) && filesize($sTempFileName) > 0) {
                    $aSize = getimagesize($sTempFileName); // try to obtain image info
                    if (!$aSize) {
                        @unlink($sTempFileName);
                        return;
                    }

                    // check for image type
                    switch($aSize[2]) {
                        case IMAGETYPE_JPEG:
                            $sExt = '.jpg';

                            // create a new image from file 
                            $vImg = @imagecreatefromjpeg($sTempFileName);
                            break;
                        /*case IMAGETYPE_GIF:
                            $sExt = '.gif';

                            // create a new image from file 
                            $vImg = @imagecreatefromgif($sTempFileName);
                            break;*/
                        case IMAGETYPE_PNG:
                            $sExt = '.png';

                            // create a new image from file 
                            $vImg = @imagecreatefrompng($sTempFileName);
                            break;
                        default:
                            @unlink($sTempFileName);
                            return;
                    }

                    // create a new true color image
                    $vDstImg = @imagecreatetruecolor( $iWidth, $iHeight );

                    // copy and resize part of an image with resampling
                    imagecopyresampled($vDstImg, $vImg, 0, 0, (int)$_POST['x1'], (int)$_POST['y1'], $iWidth, $iHeight, (int)$_POST['w'], (int)$_POST['h']);

                    // define a result image filename
                    $sResultFileName = $sTempFileName . $sExt;

                    // output image to file
                    imagejpeg($vDstImg, $sResultFileName, $iJpgQuality);
                    @unlink($sTempFileName);

                    return $sResultFileName;

                }
            }
        }
    }
}
}

$sImage = uploadImageFile();
echo '<div align=center><img src="'.$sImage.'" /></div>';
echo $sImage;
?>
  <!-- add styles -->
    <link href="css/main.css" rel="stylesheet" type="text/css" />
    <link href="css/jquery.Jcrop.min.css" rel="stylesheet" type="text/css" />

    <!-- add scripts -->
    <script src="js/jquery.min.js"></script>
    <script src="js/jquery.Jcrop.min.js"></script>
    <script src="js/script.js"></script>
</head>
<body>

    <div class="demo">
        <div class="bbody">

            <!-- upload form -->
            <form id="upload_form" enctype="multipart/form-data" method="post" onsubmit="return checkForm()">
                <!-- hidden crop params -->
                <input type="hidden" id="x1" name="x1" />
                <input type="hidden" id="y1" name="y1" />
                <input type="hidden" id="x2" name="x2" />
                <input type="hidden" id="y2" name="y2" />

                <h2>Step1: Please select image file</h2>
                <div><input type="file" name="image_file" id="image_file" onchange="fileSelectHandler()" /></div>

                <div class="error"></div>

                <div class="step2">
                    <h2>Step2: Please select a crop region</h2>
                    <img id="preview"/> <!-- QUESTA È LA PREVIEW -->

                    <div class="info">
                        <label>File size</label> <input type="text" id="filesize" name="filesize" />
                        <label>Type</label> <input type="text" id="filetype" name="filetype" />
                        <label>Image dimension</label> <input type="text" id="filedim" name="filedim" />
                        <label>W</label> <input type="text" id="w" name="w" />
                        <label>H</label> <input type="text" id="h" name="h" />
                    </div>

                    <input type="submit" value="Upload" />
                </div>
            </form>
        </div>
    </div>
</body>
</html>

SCRIPT.JS

function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
};

// check for selected crop region
function checkForm() {
  if (parseInt($('#w').val())) return true;
  $('.error').html('Please select a crop region and then press Upload').show();
  return false;
};

// update info by cropping (onChange and onSelect events handler)
function updateInfo(e) {
$('#x1').val(e.x);
$('#y1').val(e.y);
$('#x2').val(e.x2);
$('#y2').val(e.y2);
$('#w').val(e.w);
$('#h').val(e.h);
};

// clear info by cropping (onRelease event handler)
function clearInfo() {
$('.info #w').val('');
$('.info #h').val('');
};

function fileSelectHandler() {

// get selected file
var oFile = $('#image_file')[0].files[0];

// hide all errors
$('.error').hide();

// check for image type (jpg and png are allowed)
var rFilter = /^(image\/jpeg|image\/png)$/i;
if (! rFilter.test(oFile.type)) {
    $('.error').html('Please select a valid image file (jpg and png are allowed)').show();
    return;
}

// check for file size
if (oFile.size > 55555250 * 1024) {
    $('.error').html('You have selected too big file, please select a one smaller image file').show();
    return;
}

// preview element
var oImage = document.getElementById('preview');

// prepare HTML5 FileReader
var oReader = new FileReader();
    oReader.onload = function(e) {

    // e.target.result contains the DataURL which we can use as a source of the image
    oImage.src = e.target.result;
    oImage.onload = function () { // onload event handler

        // display step 2
        $('.step2').fadeIn(500);

        // display some basic image info
        var sResultFileSize = bytesToSize(oFile.size);
        $('#filesize').val(sResultFileSize);
        $('#filetype').val(oFile.type);
        $('#filedim').val(oImage.naturalWidth + ' x ' + oImage.naturalHeight);

        // Create variables (in this scope) to hold the Jcrop API and image size
        var jcrop_api, boundx, boundy;

        // destroy Jcrop if it is existed
        if (typeof jcrop_api != 'undefined') 
            jcrop_api.destroy();

        // initialize Jcrop
        $('#preview').Jcrop({
            minSize: [32, 32], // min crop size
            aspectRatio : 1, // keep aspect ratio 1:1
            bgFade: true, // use fade effect
            bgOpacity: .3, // fade opacity
            onChange: updateInfo,
            onSelect: updateInfo,
            onRelease: clearInfo
        }, function(){

            // use the Jcrop API to get the real image size
            var bounds = this.getBounds();
            boundx = bounds[0];
            boundy = bounds[1];

            // Store the Jcrop API in the jcrop_api variable
            jcrop_api = this;
        });
    };
};

// read selected file as DataURL
oReader.readAsDataURL(oFile);
}

jquey.Jcrop.min.css

/* jquery.Jcrop.min.css v0.9.10 (build:20120429) */
.jcrop-holder{direction:ltr;text-align:left;}
.jcrop-vline,.jcrop-hline{background:#FFF url(Jcrop.gif) top left repeat;font-size:0;position:absolute;}
.jcrop-vline{height:100%;width:1px!important;}
.jcrop-hline{height:1px!important;width:100%;}
.jcrop-vline.right{right:0;}
.jcrop-hline.bottom{bottom:0;}
.jcrop-handle{background-color:#333;border:1px #eee solid;font-size:1px;}
.jcrop-tracker{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none;height:100%;width:100%;}
.jcrop-handle.ord-n{left:50%;margin-left:-4px;margin-top:-4px;top:0;}
.jcrop-handle.ord-s{bottom:0;left:50%;margin-bottom:-4px;margin-left:-4px;}
.jcrop-handle.ord-e{margin-right:-4px;margin-top:-4px;right:0;top:50%;}
.jcrop-handle.ord-w{left:0;margin-left:-4px;margin-top:-4px;top:50%;}
.jcrop-handle.ord-nw{left:0;margin-left:-4px;margin-top:-4px;top:0;}
.jcrop-handle.ord-ne{margin-right:-4px;margin-top:-4px;right:0;top:0;}
.jcrop-handle.ord-se{bottom:0;margin-bottom:-4px;margin-right:-4px;right:0;}
.jcrop-handle.ord-sw{bottom:0;left:0;margin-bottom:-4px;margin-left:-4px;}
.jcrop-dragbar.ord-n,.jcrop-dragbar.ord-s{height:7px;width:100%;}
.jcrop-dragbar.ord-e,.jcrop-dragbar.ord-w{height:100%;width:7px;}
.jcrop-dragbar.ord-n{margin-top:-4px;}
.jcrop-dragbar.ord-s{bottom:0;margin-bottom:-4px;}
.jcrop-dragbar.ord-e{margin-right:-4px;right:0;}
.jcrop-dragbar.ord-w{margin-left:-4px;}
.jcrop-light .jcrop-vline,.jcrop-light .jcrop-hline{background:#FFF;filter:Alpha(opacity=70)!important;opacity:.70!important;}
.jcrop-light .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#000;border-color:#FFF;border-radius:3px;}
.jcrop-dark .jcrop-vline,.jcrop-dark .jcrop-hline{background:#000;filter:Alpha(opacity=70)!important;opacity:.7!important;}
.jcrop-dark .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#FFF;border-color:#000;border-radius:3px;}
.jcrop-holder img,img.jcrop-preview{max-width:none;}

如若不理解,可下载完整脚本。(对我的英语表示抱歉,我是意大利人) 下载链接:http://dfiles.eu/files/6yazp1des
2个回答

21

虽然回复晚了,但希望可以帮助其他人处理在JCrop中的大图片。您无需做任何更大的事情,只需提供像这样的JCrop参数即可:

 $('#cropbox').Jcrop({
      aspectRatio: 1,  //If you want to keep aspectRatio
      boxWidth: 650,   //Maximum width you want for your bigger images
      boxHeight: 400,  //Maximum Height for your bigger images
      onSelect: updateCoords 
 },function()
 {
      alert('Now you see smaller preview of your bigger one.');
 });

好消息是,当您裁剪图像并获取其尺寸时,您将获得真实的图像尺寸,即您大图像的尺寸,因此您可以在服务器上裁剪图像而无需再次计算任何内容,只需发送尺寸并进行裁剪。


1
@Abdul Jabbar:非常感谢,这对我也有用,你不知道我有多沮丧,特别是对于大肖像图片、大分辨率,设置boxWidth、boxHeight解决了我的问题,而我在实际的插件文档http://deepliquid.com/content/Jcrop_Manual.html中没有找到这个。 - Satinder singh
@Satindersingh,我很高兴它对你有帮助。不客气。 - Airy
3
我也遇到了同样的问题,但是不太理解这个答案。首先,我应该把这段代码放在哪里?是在SCRIPT.JS文件中吗?另外,为什么要在这里调用一个函数?谢谢您提前的帮助。 - Colin R. Turner
我有同样的情况,但无法调整大图像大小。`Jcrop.load('target').then(img => { jcp = Jcrop.attach(img, { multi: true }); Jcrop.setOptions({ boxWidth: 500, minSize: [200, 300], }); });` - Utsav Upadhyay
@UtsavUpadhyay,我不明白你遇到了什么问题?顺便说一句,已经过去将近7年了,我对这个库的记忆不太清楚。希望我能回答你的问题。 - Airy
我正在尝试处理上传的覆盖所有页面的大图像。在上传时如何管理宽度和高度?我已经发布了一个小片段,或者您可以查看这个fiddle。如果我上传一个大图像,它会覆盖整个Web浏览器。@Airy - Utsav Upadhyay

2

我会谨慎选择措辞,以便更好地为您翻译。

将图像缩小以适应jcrop窗口是一项复杂的任务。 我使用ColdFusion进行操作,因此没有php的示例供您参考。 相反,我将给出一个列表,告诉您该怎么做。

  1. 上传图片
  2. 读取图像尺寸
  3. 以固定比例显示图像,使其适合您的窗口
  4. 确定您的缩小后的图像与全尺寸图像的比率
  5. 将jCrop提供的裁剪X,Y,宽度和高度值乘以您的比例系数
  6. 将裁剪应用于原始图像,但使用步骤5中获得的值

这个常见问题是获取不是整数的裁剪值,通常需要将任何值向下舍入到最近的整数,以避免可能出现裁剪值大于图像的情况。


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