Последующая ошибка загрузки изображения BLOB-объекта HTML5 CreateObjectURL и обрезки

Я пытаюсь выяснить, виноват ли мой код или текущая реализация файлового API HTML5.

Код ниже работает. Ошибка появляется при повторении процесса после того, как изображение уже было загружено один раз.

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

Будем признательны за любую помощь.

Используемые библиотеки JavaScript

  • JQuery 1.7.1

  • Инструменты JQuery 1.2.6

  • JCrop 0.9.9

Шаги — сводка

  1. Пользователь выбирает файл с помощью традиционного диалог.

  2. Обработчик onchange выполняется для ввода и проверяет, был ли файл выбран, если да, то проверяет, что тип MIME — изображение/jpeg или image/png и что размер выбранного файла меньше 250 КБ. Если эта проверка не проходит, она сбрасывает выбор.

  3. В этот момент загружаемый файл (изображение) действителен. Далее это проверяет, поддерживает ли браузер файловый API CreateObjectURL через , если (typeof window.URL == 'undefined') return;(если это не так, пропускает следующие шаги)

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

  5. Затем пользователь обрезает изображение с помощью jcrop и закрывает оверлей, видя обрезанный предварительный просмотр изображения, которое будет загружено (только если браузер поддерживает CreateObjectURL и пользователь обрезает изображение)

Код

HTML

<div style="height: 100px; overflow: hidden; width: 100px; margin-bottom: 5px;">
    <img id="PhotoPreview" alt="Photo" src="/Content/no-photo.png" />
</div>
<input type="file" id="Photo" name="Photo" onchange="photoChanged(this.files)" />
<input type="hidden" id="PhotoCrop" name="PhotoCrop" value="" />

JavaScript окно.URL = окно.URL || окно.webkitURL;

function photoChanged(files) {
    if (!files.length) return;
    var file = files[0];
    if (file.type != 'image/jpeg' && file.type != 'image/png') {
        alert('The photo must be in PNG or JPEG format');
        $("#Photo").val('');
        return;
    }
    var fileSizeLimit = 250;
    var fileSize = file.size / 1024;
    if (fileSize > fileSizeLimit) {
        var fileSizeString = fileSize > 1024 ? (fileSize / 1024).toFixed(2) + "MB" : (fileSize).toFixed(2) + "KB";
        alert("The photo file size is too large, maximum size is " + fileSizeLimit
                + "KB. This photos' file size is: " + fileSizeString);
        $("#Photo").val('');
        return;
    }

    if (typeof window.URL == 'undefined') return;

    var preview = document.getElementById('PhotoPreview');
    $(preview).removeClass('profile-photo');
    preview.src = window.URL.createObjectURL(file);
    preview.onload = function () {
        var img = new Image();
        $("#PhotoOverlay div").empty().append(img);
        window.URL.revokeObjectURL(this.src);
        img.src = window.URL.createObjectURL(file);
        img.onload = function () {
            window.URL.revokeObjectURL(this.src);
            $(this).Jcrop({
                onSelect: onImageCropSelect,
                aspectRatio:
                310 / 240,
                minSize: [100, 100],
                setSelect: [0, 0, 100, 100]
        });

        $("#PhotoOverlay")
            .css({ width: this.width + 'px', : 'auto'})
            .overlay()
            .load();
        };
    };
}

function onImageCropSelect(e) {
    $("#PhotoCrop").val(e.x + ',' + e.y + ',' + .x2 + ',' + e.y2);

    var rx = 100 / e.w;
    var ry = 100 / e.h;

    var height = $("#PhotoOverlay div img").height();
    var width = $("#PhotoOverlay div img").width();

    jQuery('#PhotoPreview').css({
        width: Math.round(rx * width) + 'px',
        height: Math.round(ry * height) + 'px',
        marginLeft: '-' + Math.round(rx * e.x) + 'px',
        marginTop: '-' + Math.round(ry * e.y) + 'px'
    });
}

$(function () {
    $("#PhotoOverlay").overlay({
        mask: {
            color: '#ebecff',
            loadSpeed: 200,
            opacity: 0.9
        }
    });
});

Не стесняйтесь использовать код (мой вклад за любую помощь, полученную здесь).

Обновление

Я столкнулся с другим вопросом в stackoverflow, касающимся аналогичной проблемы (загрузка изображения и его исчезновение) в отношении использования JCrop. В настоящее время я делаю ставку на то, что виноват JCrop.

Я также читал, что при выполнении img.onload образ не всегда «готов», поэтому странное поведение и дополнительные проверки .actualWidth/.actualHeight с setTimeout могут решить проблему. Я расследую это.

Обновление

У меня есть рабочее доказательство концепции с использованием FileReader и readAsDataUrl вместо использования CreateObjectURL и использования CANVAS для предварительного просмотра вместо решения overflow:hidden на основе полей. Нуждается в некоторой доработке, тогда я опубликую код здесь.

10
задан Shelakel 20 March 2012 в 15:18
поделиться