2012-03-18 19 views
10

Sto cercando di capire se il mio codice è in errore o l'attuale implementazione dell'API del file HTML5.Successive HTML5 CreateObjectURL blob anteprima delle immagini e ritaglio del bug di caricamento

Il codice seguente funziona. Il bug appare quando si ripete il processo dopo aver già caricato l'immagine una volta.

La seconda volta che viene selezionato un file, il blob dell'immagine viene caricato, quindi si verifica uno sfarfallio e l'immagine scompare. Successive selezioni dopo di solito funzionano bene (a volte c'è un comportamento irregolare se il file è grande). La ripetizione del processo per la stessa selezione di file generalmente funziona (come correzione).

Qualsiasi aiuto sarebbe molto apprezzato.

librerie JavaScript usati

  • JQuery 1.7.1

  • JQuery Tools 1.2.6

  • JCrop 0.9.9

Steps - Summ ARY

  1. L'utente seleziona un file tramite la tradizionale finestra di dialogo <input type="file" /> .

  2. Un gestore onchange esegue per l'ingresso e controlla se un file è stato selezionato, in caso affermativo, quindi verifica che il tipo MIME è image/jpeg o image/png e che la dimensione del file selezionato è più piccolo di 250KB. Se questa convalida fallisce, ripristina la selezione.

  3. A questo punto il file (immagine) da caricare è valido. Il prossimo controlla se il browser supporta il CreateObjectURL API File tramite if (typeof window.URL == 'undefined') return; (se non lo fa, salta i passi successivi)

  4. carica il blob immagine nella pagina attuale anteprima (quello usato per visualizzare la corrente immagine) e anche in un elemento immagine generato dinamicamente che viene aggiunto in una sovrapposizione di strumenti jQuery con la funzionalità di ritaglio jcrop .

  5. L'utente ritaglia quindi l'immagine tramite jcrop e chiude la sovrapposizione, vedendo l'anteprima ritagliata dell'immagine da caricare (solo se il browser supporta CreateObjectURL e l'utente ritagliata l'immagine)

Il Codice

Il codice 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 window.URL = window.URL || finestra.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 
     } 
    }); 
}); 

Sentitevi liberi di utilizzare il codice (il mio contributo per qualsiasi aiuto ricevuto qui).

Aggiornamento

ho incontrato un'altra domanda su StackOverflow per quanto riguarda un problema simile (il caricamento delle immagini per poi scomparire) per quanto riguarda l'uso di JCrop. Al momento scommetto che JCrop è il colpevole.

Ho anche letto che quando img.onload esegue l'immagine non è sempre "pronta", quindi lo strano comportamento e i controlli aggiuntivi su .actualWidth/.actualHeight con un setTimeout potrebbero risolvere il problema. Lo indagherò.

Aggiornamento

ho una prova di lavoro di concetto con un FileReader e readAsDataUrl invece di utilizzare il CreateObjectURL e l'utilizzo di una tela per disegnare in anteprima al posto di un overflow basato margin: soluzione di nascosto. Ho bisogno di un po 'di perfezionamento, quindi posterò il codice qui.

+0

penso che sarebbe meglio utilizzare l'API jCrop e utilizzare un gestore generica o URL statico per caricare il tuo immagini. Ho realizzato un raccoglitore che può ritagliare un numero illimitato di foto una dopo (usando un gestore generico che ha passato i blob di immagini da sql db) l'altro in questo modo - senza usare l'API qualcosa di strano stava accadendo ... – ppumkin

risposta

2

comportamento spesso irregolare si verifica quando si imposta img.src prima di dichiarare 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 

speranza che questo aiuta

Problemi correlati