Подтвердить что ты не робот

Обрезание изображений в браузере перед загрузкой

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

Как сделать обрезку изображения на стороне клиента, используя некоторую функцию HTML5 без использования какого-либо кода на стороне сервера.

Если да, есть ли примеры или подсказки?

4b9b3361

Ответ 1

Да, это можно сделать.
Он основан на новом атрибуте html5 "загрузка" якорных тегов.
Поток должен быть примерно таким:

  • загрузить изображение
  • нарисуйте изображение в холсте с указанными границами урожая.
  • получить данные изображения с холста и сделать его атрибутом href для тега привязки в dom
  • добавить атрибут загрузки (download="desired-file-name") к этому элементу a Это. все, что вам нужно сделать, это нажать "ссылку для загрузки", и изображение будет загружено на его компьютер.

Я вернусь с демоверсией, когда я получу шанс.

Обновление
Здесь живая демонстрация, как я и обещал. Он принимает логотип jsfiddle и посещает 5px каждого поля.
Код выглядит следующим образом:

var img = new Image();
img.onload = function(){
    var cropMarginWidth = 5,
        canvas = $('<canvas/>')
                    .attr({
                         width: img.width - 2 * cropMarginWidth,
                         height: img.height - 2 * cropMarginWidth
                     })
                    .hide()
                    .appendTo('body'),
        ctx = canvas.get(0).getContext('2d'),
        a = $('<a download="cropped-image" title="click to download the image" />'),
        cropCoords = {
            topLeft : {
                x : cropMarginWidth,
                y : cropMarginWidth 
            },
            bottomRight :{
                x : img.width - cropMarginWidth,
                y : img.height - cropMarginWidth
            }
        };

    ctx.drawImage(img, cropCoords.topLeft.x, cropCoords.topLeft.y, cropCoords.bottomRight.x, cropCoords.bottomRight.y, 0, 0, img.width, img.height);
    var base64ImageData = canvas.get(0).toDataURL();


    a
        .attr('href', base64ImageData)
        .text('cropped image')
        .appendTo('body');

    a
        .clone()
        .attr('href', img.src)
        .text('original image')
        .attr('download','original-image')
        .appendTo('body');

    canvas.remove();
}
img.src = 'some-image-src';

Обновление II
Забыл упомянуть: конечно, есть недостаток:(.
Из-за той же политики происхождения, которая применяется к изображениям, также, если вы хотите получить доступ к данным изображения (с помощью метода холста toDataUrl).
Таким образом, вам все равно нужен серверный прокси-сервер, который будет служить вашему изображению, как если бы он размещался в вашем домене.

Обновление III Хотя я не могу предоставить демо-версию для этого (по соображениям безопасности), вот пример кода PHP, который решает политику одного и того же происхождения:

file proxy.php:

$imgData = getimagesize($_GET['img']);
header("Content-type: " . $imgData['mime']);
echo file_get_contents($_GET['img']);  

Таким образом, вместо загрузки внешнего изображения непосредственно из него:

img.src = 'http://some-domain.com/imagefile.png';

Вы можете загрузить его через свой прокси:

img.src = 'proxy.php?img=' + encodeURIComponent('http://some-domain.com/imagefile.png');  

И вот пример php-кода для сохранения данных изображения (base64) в фактическое изображение:

file save-image.php:

$data = preg_replace('/data:image\/(png|jpg|jpeg|gif|bmp);base64/','',$_POST['data']);
$data = base64_decode($data);
$img = imagecreatefromstring($data);

$path = 'path-to-saved-images/';
// generate random name
$name  = substr(md5(time()),10);
$ext = 'png';
$imageName = $path.$name.'.'.$ext;

// write the image to disk
imagepng($img,  $imageName);
imagedestroy($img);
// return the image path
echo $imageName;

Все, что вам нужно сделать, это отправить данные изображения в этот файл, и он сохранит изображение на диск и вернет вам существующее имя файла изображения.

Конечно, все это может показаться немного сложным, но я хотел показать вам, что то, что вы пытаетесь достичь, возможно.

Ответ 2

Pixastic библиотека делает именно то, что вы хотите. Тем не менее, он будет работать только в браузерах, которые поддерживают холст. Для более старых браузеров вам необходимо:

  1. предоставить запасной вариант на стороне сервера или
  2. Скажите пользователю, что вы очень сожалеете, но ему нужно получить более современный браузер.

Конечно, вариант № 2 не очень удобен для пользователя. Тем не менее, если вы намереваетесь предоставить исключительно клиентский инструмент и/или вы не можете поддерживать резервный серверный компонент (например, вы пишете расширение для браузера или автономное приложение Chrome, или, возможно, вы не можете себе позволить достойный хостинг-провайдер, который предоставляет библиотеки для работы с изображениями), тогда было бы справедливо ограничить вашу пользовательскую базу современными браузерами.

РЕДАКТИРОВАТЬ: если вы не хотите изучать Pixastic, я добавил очень простой инструмент для jsFiddle здесь. Должна быть возможность изменять, интегрировать и использовать функцию drawCroppedImage с Jcrop.

Ответ 3

#change-avatar-file - вход в файл #change-avatar-file является тегом img (цель jcrop) "Ключ" - это событие FR.onloadend https://developer.mozilla.org/en-US/docs/Web/API/FileReader

$('#change-avatar-file').change(function(){
        var currentImg;
        if ( this.files && this.files[0] ) {
            var FR= new FileReader();
            FR.onload = function(e) {
                $('#avatar-change-img').attr( "src", e.target.result );
                currentImg = e.target.result;
            };
            FR.readAsDataURL( this.files[0] );
            FR.onloadend = function(e){
                //console.log( $('#avatar-change-img').attr( "src"));
                var jcrop_api;

                $('#avatar-change-img').Jcrop({
                    bgFade:     true,
                    bgOpacity: .2,
                    setSelect: [ 60, 70, 540, 330 ]
                },function(){
                    jcrop_api = this;
                });
            }
        }
    });

Ответ 4

Если вы все еще будете использовать JCrop, вам понадобятся только эти функции php для обрезки файла:

$img_src = imagecreatefromjpeg($src);
$img_dest = imagecreatetruecolor($new_w,$new_h);
imagecopyresampled($img_dest,$img_src,0,0,$x,$y,$new_w,$new_h,$w,$h);
imagejpeg($img_dest,$dest);

клиентская сторона:

jQuery(function($){

    $('#target').Jcrop({
    onChange:   showCoords,
    onSelect:   showCoords,
    onRelease:  clearCoords
    });

});

var x,y,w,h; //these variables are necessary to crop
function showCoords(c)
{
    x = c.x;
    y = c.y;
    w = c.w;
    h = c.h;
};
function clearCoords()
{
    x=y=w=h=0;
}