Последующий HTML5 CreateObjectURL blob просмотр изображения и обрезка ошибка загрузки

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

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

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

любая помощь была бы весьма признательна.

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

  • JQuery 1.7.1

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

  • JCrop 0.9.9

Шаги - Резюме

  1. пользователь выбирает файл с помощью традиционного <input type="file" /> диалог.

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

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

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

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

Код

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

1 ответов


часто неустойчивое поведение возникает при установке img.src прежде чем объявить img.onload

function imageLoadHandler() { ... }

var img = new Image();
img.onload = function() { imageLoadHandler() }
img.src = window.URL.createObjectURL(file);
if(img.complete) { imageLoadHandler() } //fix for browsers that don't trigger .load() event with image in cache

надеюсь, что это помогает