2015-09-22 2 views
3

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

Я использую FileReader, чтобы получить предварительный просмотр изображения, и jCrop, чтобы обрезать его.

Вот код, я использую (часть его):

var jcrop = null; 
    var reader = new FileReader(); 

    reader.onload = function (e) { 

      $('#upload-picture-sample').attr('src', e.target.result).load(function(){ 
       var img = this; 

       var imageWidth = img.width; 
       var imageHeight = img.height; 

       console.log(img.width+'-- WIDTH --'+$(this).width()); 
       console.log(img.height+'-- HEIGHT --'+$(this).height()); 

       if(imageWidth != imageHeight){ 

        var selectArray = []; 

        if(imageWidth > imageHeight){ 
         selectArray = [(imageWidth-imageHeight)/2, 0, (imageWidth-imageHeight)/2 + imageHeight, imageHeight]; 
        }else{ 
         selectArray = [0, (imageHeight - imageWidth)/2, imageWidth, (imageHeight - imageWidth)/2 + imageWidth]; 
        } 
        if(!jcrop){ 
         $('#upload-picture-sample').Jcrop({ 
          aspectRatio: 1, 
          keySupport: false, 
          addClass: 'jcrop-centered', 
          setSelect: selectArray 
         }, function(){ 
          jcrop = this; 
         }); 
        }else{ 
         jcrop.setImage(e.target.result); 
         jcrop.setSelect(selectArray); 

        } 
       } 
       $(this).unbind('load'); 
      }); 
     } 

    $('#upload-picture-file').change(function(){ 
     $('#upload-picture-send').removeClass('disabled'); 
     $('#upload-picture-error').hide(); 

     console.log('changed!'); 

     reader.readAsDataURL(this.files[0]); 
    }) 

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

Чтобы проиллюстрировать эту проблему, я загрузки:

1/picture1 (600x450)

2/Picture2 (94x125)

3/Picture1 снова (600x450)

enter image description here

Первая загрузка работает нормально, вторая работает отлично, но я думаю, что это больше удачи, чем что-то еще, поскольку высота неверно вычисляется как 0. Третья загрузка не работает (размер установлен неправильно).

Это означает, что урожай не отображается правильно.

Что касается CSS, у меня есть это:

#upload-picture-sample{ 
    display:block; 
    margin-left: auto; 
    margin-right: auto; 
    margin-bottom: 30px; 
    max-height:125px; 
    height:auto; 
    width:auto; 
    max-width:300px; 
} 

У вас есть представление о том, как я мог бы решить мою проблему?

UPDATE: После добавления setTimeout в соответствии с рекомендациями @initialxy enter image description here

Так что это гораздо лучше, но все же, первое изображение не имеет те же размеры, чем последний (и это должно быть, поскольку это точно то же изображение) Спасибо.

ответ

1

Все ваши номера выглядят непоследовательными. На первом изображении ширина в конце составляет 167 с img.width, но 167 с jQuery. Следует отметить, что jQuery получает computed style, а img.width и img.height - это свойства DOM, которые задают требуемую ширину и высоту. (FYI есть также naturalWidth и naturalHeight, которые только для чтения свойства DOM, которая получает вас исходные размеры img.)

это больше удачи, чем что-то еще

Если ваш код зависит от удачи, то у нас возникла проблема.

Похоже, что браузер выбрал событие загрузки слишком рано, так что механизм компоновки не закончил обновление DOM. load просто означает, что данные загружены, не обязательно означает, что механизм компоновки должен быть завершен. Поэтому попробуйте поставить очередь вашего кода в свою функцию загрузки позже в очереди задач. К тому, я имею в виду обернуть все это в setTimeout(..., 0); Остерегайтесь this, так как он изменился.

например.

$('#upload-picture-sample').attr('src', e.target.result).load(function(){ 
    var img = this; 

    setTimeout(function() { 
     var imageWidth = img.width; 
     var imageHeight = img.height; 

     console.log(img.width+'-- WIDTH --'+$(img).width()); 
     console.log(img.height+'-- HEIGHT --'+$(img).height()); 

     // TODO: Crop 
     ... 
    }, 0); 

    $(this).unbind('load'); 
}); 

EDIT: В ответ на @ обновление Вико. Похоже, механизм компоновки уложился на этот раз. Давайте сделаем некоторые замечания по этим числам. Размеры первого изображения были первоначально 600x450, но в итоге это было 167x125. Это имеет смысл, потому что он был изменен на max-height: 125px; свойство CSS. Второе изображение имеет оба размера менее max-width и max-height, поэтому оно не изменилось. Третье изображение имеет размеры 600x450, и оно получило эти размеры, поэтому в этот момент max-width и max-height больше не вступают в силу. Почему это? Возможно, jcrop прикручивается со стилем и переопределяет ваш стиль. Запустите свой отладчик Chrome, проверьте свой элемент img и используйте его консоль JavaScript, чтобы поиграть с ним. (Чтобы дать вам короткий ответ, да, jcrop делает винт со стилем и применяет встроенные стили к элементу, что переопределяет ваш стиль. Но эй, веселее играть с отладчиком.) Кроме того, я не уверен, почему ваш размеры справа все закончилось с 1440x514. Вы можете узнать, вкручиваясь в отладчик.

+0

Большое спасибо за ваш ответ @initialxy, я обновил сообщение, чтобы показать новые результаты. Тем не менее, у меня все еще есть странный результат для последней загрузки. Любая подсказка? – Vico

+0

Спасибо за ваше обновление @initialxy. Странно то, что изображения имеют правильный размер. Jcrop один, и оригинал (upload-picture-sample). Когда я проверяю инспектор, все кажется прекрасным. Иначе значения ширины и высоты неверны, иначе я получаю их размер до того, как применяется css. – Vico

+0

@Vico Вы используете тот же элемент для измерения размера изображения, а также для использования jcrop. jscrop применял к нему ряд встроенных стилей. Откройте ваш отладчик и выберите свой __original__ 'img' в инспекторе. (Теперь в консоли JavaScript вы можете легко ссылаться на него с помощью '$ 0'.) Что вы видите? Что-то вроде '' не так ли? Обратите внимание, что атрибут 'style' содержит в себе множество нежелательных значений? – initialxy

0

Для получения дополнительной информации, я предлагаю все потенциальные читатели, чтобы взглянуть на этот вопрос: https://github.com/tapmodo/Jcrop/issues/46

В обходные прекрасно работают.

Смежные вопросы