2012-03-18 31 views
10

Tôi đang cố gắng tìm hiểu xem mã của tôi có bị lỗi hoặc triển khai API tệp API hiện tại hay không.Tiếp theo HTML5 CreateObjectURL xem trước hình ảnh blob và lỗi tải ảnh cắt xén

Mã bên dưới hoạt động. Lỗi xuất hiện khi lặp lại quy trình sau khi đã tải hình ảnh một lần.

Lần thứ hai một tệp được chọn tải blob hình ảnh, sau đó có một nhấp nháy và hình ảnh biến mất. Các lựa chọn tiếp theo sau đó thường hoạt động tốt (đôi khi có hành vi thất thường nếu tệp lớn). Lặp lại quá trình cho cùng một lựa chọn tập tin thường hoạt động (như một sửa chữa).

Mọi trợ giúp sẽ được đánh giá cao.

thư viện JavaScript sử dụng

  • JQuery 1.7.1

  • JQuery Công cụ 1.2.6

  • JCrop 0.9.9

Steps - Summ Ary

  1. Người dùng chọn một tập tin thông qua truyền thống thoại <input type="file" /> .

  2. Một handler onchange thực hiện cho đầu vào và kiểm tra nếu một tập tin được chọn, nếu như vậy, sau đó xác nhận rằng kiểu MIME là image/jpeg hoặc image/png và kích thước tập tin được lựa chọn nhỏ hơn 250KB. Nếu xác thực này không thành công, hãy đặt lại lựa chọn.

  3. Tại thời điểm này, tệp (hình ảnh) được tải lên hợp lệ. Tiếp theo nó kiểm tra nếu trình duyệt hỗ trợ các tập tin CreateObjectURL API qua if (typeof window.URL == 'undefined') return; (nếu không, bỏ qua các bước tiếp theo)

  4. Nó tải blob ảnh vào xem trước hình ảnh hiện tại (một sử dụng để hiển thị hiện tại hình ảnh) và cũng vào phần tử hình ảnh được tạo động được thêm vào lớp phủ của công cụ jquery với jcrop chức năng cắt xén.

  5. Người dùng sau đó cắt một phần ảnh qua jcrop và đóng overlay, thấy preview cắt của hình ảnh được tải lên (chỉ khi trình duyệt hỗ trợ CreateObjectURL và người dùng cắt hình ảnh)

Bộ luật

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="" /> 

Cửa sổ JavaScript .URL = window.URL || cửa sổ.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 
     } 
    }); 
}); 

Vui lòng sử dụng mã (đóng góp của tôi cho bất kỳ trợ giúp nào nhận được tại đây).

Cập nhật

Tôi đã đi qua một câu hỏi khác trên stackoverflow liên quan đến một vấn đề tương tự (hình ảnh tải sau đó biến mất) liên quan đến việc sử dụng các JCrop. Tôi hiện đang đặt cược vào JCrop là thủ phạm.

Tôi cũng đọc rằng khi img.onload thực thi hình ảnh không phải lúc nào cũng 'sẵn sàng', do đó hành vi lạ và kiểm tra bổ sung đối với .actualWidth/.actualHeight với setTimeout có thể giải quyết vấn đề. Tôi sẽ điều tra nó.

Cập nhật

Tôi có một bằng chứng làm việc của khái niệm sử dụng một FileReader và readAsDataUrl thay vì sử dụng CreateObjectURL và sử dụng một CANVAS để vẽ một bản xem trước thay vì một biên độ tràn dựa trên: giải pháp ẩn. Cần một số sàng lọc sau đó tôi sẽ đăng mã ở đây.

+0

Tôi nghĩ rằng nó sẽ được tốt hơn để sử dụng API jCrop và sử dụng một trình xử lý chung hoặc url tĩnh để tải của bạn hình ảnh. Tôi đã thực hiện một cropper có thể cắt số lượng không giới hạn của bức ảnh một sau (sử dụng xử lý chung mà thông qua các hình ảnh blobs từ sql db) khác như thế này- mà không cần sử dụng API một cái gì đó kỳ quặc đã happeining ... – ppumkin

Trả lời

2

hành vi thường thất thường xảy ra khi bạn thiết lập img.src trước khi tuyên bố 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 

hy vọng điều này giúp

Các vấn đề liên quan