Предварительный просмотр изображения Jcrop с правильной ориентацией, измененной с использованием данных exif

У меня есть виджет обрезки изображения на сайте. Изображение обрезается пользователем с помощью Jcrop перед любой загрузкой.

Однако, когда пользователь загружает фотографию с данными об ориентации (часто с iPhone или аналогичного устройства), фотография отображается с неправильной ориентацией по отношению к нему (по сравнению с тем, когда они открываются в большинстве основных программ просмотра фотографий на своем компьютере).

Что я хотел бы сделать, так это повернуть изображение в ожидаемую ориентацию. Я пытаюсь извлечь данные exif со стороны клиента изображения, а затем использовать это, чтобы добавить класс css к изображению предварительного просмотра перед инициализацией jcrop. Класс css соответствующим образом поворачивает изображение.

На данный момент Jcrop, кажется, создает свой черный ящик (для изображения за изображением) и поле выбора кадрирования, как будто вращение никогда не происходило, но вращение изображения происходит, поэтому все выглядит неправильно.

Некоторый код из виджета, который я пытался изменить, приведен ниже. jsfiddle, включая весь код, находится здесь. Обратите внимание, что setCoords устанавливает другой ввод, который я не включил, так как не считал его уместным.

Любая помощь очень ценится.

HTML

<input type="file" />
<div id="preview-image-holder">
    <img id="preview-image" />
</div>

JavaScript

var jcrop_api, ratio=1.3, real_width, real_height;

function setCoords(c) { //function to set value of cropping coords widget to a json string of the cropping coordinates
    $('input[id*=cropping_coords]').val(JSON.stringify(c));
}

function base64ToArrayBuffer (base64) {
    base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, '');
    var binary_string =  window.atob(base64);
    var len = binary_string.length;
    var bytes = new Uint8Array( len );
    for (var i = 0; i < len; i++)        {
        bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes.buffer;
}

function fixOrientation(image, orientationNum) {
    //adds css class to image dependent on orientation number
    switch(orientationNum) {
        case 2:
            image.addClass('flip'); break;
        case 3:
            image.addClass('rotate-180'); break;
        case 4:
            image.addClass('flip-and-rotate-180'); break;
        case 5:
            image.addClass('flip-and-rotate-270'); break;
        case 6:
            image.addClass('rotate-90'); break;
        case 7:
            image.addClass('flip-and-rotate-90'); break;
        case 8:
            image.addClass('rotate-270'); break;
    }
}

function initJcrop(selector) {
    //intialises jcrop on image
    $(selector).Jcrop({
        onSelect:setCoords,
        onChange:setCoords,
        bgColor:'black',
        bgOpacity:0.4,
        aspectRatio:ratio,
        trueSize:[real_width, real_height]
    }, function() {
        jcrop_api = this;
        dim = jcrop_api.getBounds();
        var x = 0, y = 0, x_ = dim[0], y_ = dim[1];
        var x_r = (x_ / ratio) - y_;
        var y_r = (y_ / ratio) - x_;

        if (x_r > 0) {
            x = x_r / 2;
        }
        if (y_r > 0) {
            y = y_r / 2;
        }
        jcrop_api.setSelect([x, y, dim[0], dim[1]]);
        jcrop_api.setOptions({
            allowSelect:false
        });
    });
}

function readImageURL(input) {
    //uses FileReader to change source of #preview-image to 
    //image from input
    if (input.files && input.files[0]) {
        var reader = new FileReader();

        reader.onload = function (e) {
            if(jcrop_api !== undefined) {
                jcrop_api.destroy();
                $('#preview-image').removeAttr('style');
            }
            var exif = EXIF.readFromBinaryFile(base64ToArrayBuffer(e.target.result));
            console.log(parseInt(exif.Orientation));
            var orientation = parseInt(exif.Orientation);
            fixOrientation($('#preview-image'), orientation);
            $('#preview-image').attr('src', e.target.result);
            $('<img />').attr('src', e.target.result).load(function() {
                if ([5,6,7,8].indexOf(orientation)) {
                    real_width = this.height;
                    real_height = this.width;
                } else {
                    real_width = this.width;
                    real_height = this.height;
                }
                initJcrop($('#preview-image'));
            });
        };
        reader.readAsDataURL(input.files[0]);

    }
}

$('input').change(function() {
    readImageURL(this);
});

person lac    schedule 05.10.2015    source источник
comment
Вам повезло с этим в конце концов?   -  person meakeel    schedule 10.12.2015
comment
Тоже с этой проблемой. Элемент изображения jcrop за панелью предварительного просмотра — это ориентация фактического изображения, но рабочая область обрезки — это повернутая ориентация. в конце обрезка соответствует тому, что выбрал пользователь, но панель предварительного просмотра растянута из-за противоположной ориентации ... все еще ищет решение и похоже на ту же проблему, что и у вас   -  person GWR    schedule 02.04.2016
comment
stackoverflow.com/questions/36034437/   -  person Abram    schedule 26.05.2016