Generate Image Thumbs Before Uploading

Asked

Viewed 238 times

2

I am looking for a solution without plugins that manages Thumbs of the selected images on <input type="file"/>, preferably with Javascript or at most jQuery.

The idea is to have something like this structure:

<div class="row">
  <div class="col-md-12">
    <input type="file" multiple/>
  </div>
  <div class="col-md-12">
    <div class="col-md-2">
    <img src="https://placehold.it/150?text=base64" />
    </div>
    <div class="col-md-2">
        <img src="https://placehold.it/150?text=base64" />
    </div>
    <div class="col-md-2">
        <img src="https://placehold.it/150?text=base64" />
    </div>
    <div class="col-md-2">
        <img src="https://placehold.it/150?text=base64" />
    </div>
    <div class="col-md-2">
        <img src="https://placehold.it/150?text=base64" />
    </div>
    <div class="col-md-2">
        <img src="https://placehold.it/150?text=base64" />
    </div>
  </div>
</div>
  • take a look: https://github.com/alineDiesel/Otimizacao-de-memoria-carregamento-de-imagens/blob/master/Teste.html

2 answers

0

<input type="file" id="inp-select-img" multiple="multiple" />
<div id="div-conteudo">
    <div id="div-imgs">
    </div>
</div>


    var _imgCarregando = new Image();
    var _arrayUrls = new Array();

    $(document).ready(function () {
        $("#inp-select-img").change(function (data) {
            $("#inp-select-img").html("");
            var countLocal = _arrayUrls.length;
            var indiceControle = _arrayUrls.length;
            $.each(data.target.files, function (indice, obj) {
                _arrayUrls.push({ "indice": countLocal, "url": obj, "type": obj.type });
                countLocal += 1;
            });
            carregarArquivo(_arrayUrls[indiceControle]);
        });
    });

    function carregarArquivo(obj) {
        if (obj) {
            if (obj.type.match('image.*')) {
                var url = window.URL.createObjectURL(obj.url);
                _imgCarregando.onload = function () {
                    var canvas = document.createElement("canvas");
                    canvas.height = 150;
                    canvas.width = this.width * canvas.height / this.height;
                    var ctx = canvas.getContext("2d");
                    ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
                    $("#div-imgs").append("<img height='150' class='img-editar' id=" + obj.indice + " src=''/>");
                    var arqFinal = canvas.toDataURL(obj.type, 1);
                    $("#" + obj.indice).attr("src", arqFinal);
                    window.URL.revokeObjectURL(url);
                    $('html, body').prop("scrollTop", $("#div-imgs").height());
                    carregarArquivo($.grep(_arrayUrls, function (objAbrir) { return objAbrir.indice == obj.indice + 1; })[0]);
                };
                _imgCarregando.src = url;
            }
        } else
            _imgCarregando = new Image();
    }

The images are loaded one by one so as not to overflow memory in the rendering. There are other ways to render a Thumb of a selected image, such as Filereader for reading, for example, and reduced rendering of the image itself, however, it consumes quite considerable memory. Thinking of loading multiple images and not so much control of file size. The difference with createObjectURL is that it 'creates a url' based on your document with the file data and the revokeObjectURL call then removes it from its relationship to the page and its need for existence. I had problem still with memory in FF, after I stopped seeing, but I did a timeout when the browser is FF to continue loading and give a little release time rendering.

0

You can use the class FileReader javascript.

This code has been implemented and changed based on another question. See the source!

function readURL() {
  if (this.files && this.files[0]) {
    var reader = new FileReader();
    reader.onload = function (e) {
      $('#blah')
        .show()
        .attr('src', e.target.result)
        .width(350)
        .height(350);
    };
    reader.readAsDataURL(this.files[0]);
  }
}

$('[type="file"]').on('change', readURL);
#blah {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='file' />
<img id="blah" src="#" alt="your image" />

  • The bid is to upload multiple images, as you would be using a input multiple?

  • @Kennyrafael just make a loop, note that the file is on this.files[0], then make a for or while to scroll through all images.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.