Intereting Posts

Устранение неполадок и изменение размера изображения

Я пытаюсь создать уменьшенное изображение для большего изображения. Я использую Jcrop для получения координат урожая, но я не могу превратить это в правильно обрезанное миниатюрное изображение. Я правильно настроил Jcrop, и он отправляет координаты xy вместе с размером поля, но я не могу понять, как это сделать.

У меня есть путь к изображению на моем сервере, а также 4 координаты и ширина и высота квадратного окна, которое они создают (я заблокировал соотношение сторон к 1: 1, так как я хочу квадратные миниатюры). Затем я отправляю это через Ajax на свой скрипт обрезки PHP, но я не могу заставить его обрезать его на основе того, что установлено.

Это то, что у меня есть до сих пор:

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'; } 

Я пробовал менять всевозможные вещи в imagecopyresampled но не могу заставить его обрезать, как передает Jcrop. Если я использую $srcWidth и $srcHeight он поддерживает соотношение сторон исходного изображения и скручивает его в квадрат 180 пикселей. Но, похоже, это не изменяет размер или не подрезает его с нужного места.

Может кто-то, пожалуйста, помогите мне разобраться, какие цифры я должен использовать где? Я весь день бил головой об этом.


    РЕДАКТИРОВАТЬ

    Вот остальная часть кода. Сначала JavaScript, который запускает JCrop. Он запускается после загрузки файла Ajax для создания миниатюры этого изображения:

    Это функция загрузки Ajax, которая в конце вызывает обрезку.

     $(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')); }); }); 

    Это отправляет данные об уроках через скрипт PHP через 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); }); 

    Окно обрезки – это лайтбокс, эта функция вертикально центрирует его и изменяет размер изображения, если оно больше по вертикали, чем доступное пространство.

     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 и очистить лайтбокс урожая, готовый для обрезания следующего изображения.

     function CropSuccess() { $('.crop').fadeOut(250, function() { jcrop.destroy(); $(this).html(''); CropWorker(); }); } 

    Это рабочий, который фактически создает контент в лайтбокс и инициирует 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, и кажется, что мы почти там.

    Для меньших изображений те, кто под 1000px, кажется, работают отлично. Но для более крупных (1000px +) он создает черные изображения. Он не делает этого, когда я использую его с демо-скриптом JCrop, но единственная разница между ними – это вывод файла на экран, а другой – его сохранение. Я не вижу другой разницы или не понимаю, почему это произойдет.

    ОБНОВЛЕНИЕ 2 Кажется, это затронуто только в том случае, если я запускаю код через Ajax. Если я запускаю ту же самую функцию, просто отправляя ее на страницу и запуская ее вверху, миниатюра создается идеально каждый раз, независимо от размера исходного изображения или размера ящика.

    Related of "Устранение неполадок и изменение размера изображения"