Ir ao conteúdo
  • Cadastre-se

PHP Redimensionar imagens sem perder qualidade após upload


Posts recomendados

bom dia a todos. Sou nova nesse fórum e preciso de um help!

Estou desenvolvendo um sistema de postagem de notícias para o setor responsável aqui da empresa onde trabalho e cada notícia possui várias imagens. Eles me pediram que esse sistema de upload deixasse selecionar todas as imagens de uma unica vez e redimensioná-las para o tamanho certo sem que eles tenham que se preocupar com isso.
Encontrei um script que faça isso. Para selecionar todas de uma vez, está ok, meu problema é que ao redimensionar as imagens, elas estão perdendo muito a qualidade.
Encaminho o arquivo contendo todo o processo que segui para fazer o sistema de upload.

Está sendo usado nesse sistema as bibliotecas: canvas-to-blob.min.js e resize.js. 

Redimensionar imagem antes de enviar com Javascript.docx

Link para o comentário
Compartilhar em outros sites

Tenta adaptar o script abaixo:


 

   function resize(direction) {

      var width;
      var height;
      var element = document.getElementById('target');

      if (direction == 1) {

        width = Math.round((element.clientWidth * 1.15));
        height = Math.round((element.clientHeight * 1.15));

      } else {

        width = Math.round((element.clientWidth / 1.15));
        height = Math.round((element.clientHeight / 1.15));
      }

      if ((width < parseInt(jQuery('#hdfConfiguracaoW').val())) && (height < parseInt(jQuery('#hdfConfiguracaoH').val()))) {

        if (parseInt(width) != 0 && parseInt(height) != 0) {

          document.getElementById('hdfDirection').value = parseInt(document.getElementById('hdfDirection').value) + direction;

          element.style.width = width + 'px';
          element.style.height = height + 'px';

          document.getElementById('hdfTamanhoFinalW').value = width;
          document.getElementById('hdfTamanhoFinalH').value = height;

        }
      } else {

        alert('Tamanho máximo permitido para uma imagem foi atingido.');
      }      
    }

 

Link para o comentário
Compartilhar em outros sites

  • Moderador

@Gisele Passoni Olá, seja bem vinda em nosso Clube do Hardware.

 

Sem um código fica difícil tentar ajudar. O código acima, é feito com jQuery. A função deve ser adaptada dentro da função que você usa, em conjunto com o canvas-to-blob.min.js e resize.js.

 

De qualquer forma, não recomendo copiar e colar, provavelmente não vai funcionar.

 

 

PS: Evite ao máximo anexar arquivos de word com código. Não é todos que podem abri-lo, eu por exemplo não tenho como abrir no momento. Por isso a importância de colocar o código em texto aqui no fórum com o botão CODE <> no editor.

Link para o comentário
Compartilhar em outros sites

Ok, @DiF segue então os 2 arquivos...

 

arquivo fotos.php

<?php
$sql="select * from noticias where id = $cod"; //$cod vem por get
$resultado = $conexao->query($sql);
$d=mysqli_fetch_array($resultado);
$pasta=$d['pasta'];
$diretorio= "fotos/$pasta";
mkdir("$diretorio", 0777);
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Cadastro de Foto</title>
    <script src="js/jquery-2.0.3.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/canvas-to-blob.min.js"></script>
    <script src="js/resize.js"></script>
    <link rel="stylesheet" href="js/bootstrap.min.css">
    <script type="text/javascript">
        // Iniciando biblioteca
        var resize = new window.resize();
        resize.init();
        // Declarando variáveis
        var imagens;
        var imagem_atual;
       // Quando carregado a página
        $(function ($) {
            // Quando selecionado as imagens
            $('#imagem').on('change', function () {
                enviar();
            });
        });
        /*
         Envia os arquivos selecionados
         */
        function enviar()
        {
            // Verificando se o navegador tem suporte aos recursos para redimensionamento
            if (!window.File || !window.FileReader || !window.FileList || !window.Blob) {
                alert('O navegador não suporta os recursos utilizados pelo aplicativo');
                return;
            }
            // Alocando imagens selecionadas
            imagens = $('#imagem')[0].files;
            // Se selecionado pelo menos uma imagem
            if (imagens.length > 0)
            {
                // Definindo progresso de carregamento
                $('#progresso').attr('aria-valuenow', 0).css('width', '0%');
                // Escondendo campo de imagem
                $('#imagem').hide();
                // Iniciando redimensionamento
                imagem_atual = 0;
                redimensionar();
            }
        }
        /*
         Redimensiona uma imagem e passa para a próxima recursivamente
         */
        function redimensionar()
        {
            // Se redimensionado todas as imagens
            if (imagem_atual > imagens.length)
            {
                // Definindo progresso de finalizado
                $('#progresso').html('Imagen(s) enviada(s) com sucesso');
                // Limpando imagens
                limpar();
                // Exibindo campo de imagem
                $('#imagem').show();
                // Finalizando
                return;
            }
            // Se não for um arquivo válido
            if ((typeof imagens[imagem_atual] !== 'object') || (imagens[imagem_atual] == null))
            {
                // Passa para a próxima imagem
                imagem_atual++;
                redimensionar();
                return;
            }
            // Redimensionando
            resize.photo(imagens[imagem_atual], 600, 'dataURL', function (imagem) {
                // Salvando imagem no servidor
                $.post('upload.php', {imagem: imagem}, function() {
                    // Definindo porcentagem
                    var porcentagem = (imagem_atual + 1) / imagens.length * 100;
                    // Atualizando barra de progresso
                    $('#progresso').text(Math.round(porcentagem) + '%').attr('aria-valuenow', porcentagem).css('width', porcentagem + '%');
                    // Aplica delay de 1 segundo
                    // Apenas para evitar sobrecarga de requisições
                    // e ficar visualmente melhor o progresso
                    setTimeout(function () {
                        // Passa para a próxima imagem
                        imagem_atual++;
                        redimensionar();
                    }, 1000);
                });
            });
        }
        /*
         Limpa os arquivos selecionados
         */
        function limpar()
        {
            var input = $("#imagem");
            input.replaceWith(input.val('').clone(true));
        }
    </script>
</head>
<body>
<div class="container">
    <h1>Cadastro de Foto</h1>
    <form method="post" action="#" role="form">
        <div class="progress">
            <div id="progresso" class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="0"
                 aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div>
        </div>
        <div class="form-group row">
            <div class="col-xs-12">
                <input id="imagem" type="file" accept="image/*" multiple/>
            </div>
        </div>
    </form>
</div>
</body>
</html>

Arquivo upload.php

<?php
$pasta="fotos/$pasta";
// Recuperando imagem em base64
// Exemplo: data:image/png;base64,AAAFBfj42Pj4
$imagem = $_POST['imagem'];
// Separando tipo dos dados da imagem
// $tipo: data:image/png
// $dados: base64,AAAFBfj42Pj4
list($tipo, $dados) = explode(';', $imagem);
// Isolando apenas o tipo da imagem
// $tipo: image/png
list(, $tipo) = explode(':', $tipo);
// Isolando apenas os dados da imagem
// $dados: AAAFBfj42Pj4
list(, $dados) = explode(',', $dados);
// Convertendo base64 para imagem
$dados = base64_decode($dados);
// Gerando nome aleatório para a imagem
$nome = md5(uniqid(time()));
// Salvando imagem em disco
file_put_contents("$pasta/{$nome}.jpg", $dados);
?>

 

Link para o comentário
Compartilhar em outros sites

  • Moderador

@Gisele Passoni Analisei seu código, a "princípio" não vi erros. Pode ser que seja um erro no próprio arquivo js do resize.

Mas notei que no PHP, você usa o file_put_contents para o upload. O ideal é usar a função move_uploaded_file()

 

Agora eu te pergunto, onde você guarda as fotos quando fizer o upload? em um diretório do servidor?

Há mesmo necessidade de redimensiona-las?  Não seria mais simples você limitar o tamanho delas via CSS?

 

Por exemplo:

 

Vamos supor que fez o upload de uma foto com dimensões de 600x800.   Mas quer redimensionar sem perder a qualidade

 

No elemento onde vai mostrar a foto você defin o CSS assim:

.container img {
    max-width: 200px;
    max-height:250px;
    width: auto;
    height: auto;
}
.container {
    clear: both;
    margin-top: 20px;
}
img {
    vertical-align: top
}

Assim você diz que a foto vai ter um máximo de 200 x 250  e width e height são automáticos.

Exemplo online: https://jsfiddle.net/dife/t280nx4v/1/

 

Por outro lado, como você já usa o jQuery... pode redimensionar com ele assim:

 

CSS:

.container .fakeImg {
    background: no-repeat center;
    background-size: cover;    
}

.container
{
    display:inline-block;
    border:2px solid red;
    margin: 4px;
}

Jquery:

$('.container img').replaceWith(function(i, v){
    return $('<div/>', {
        style: 'background-image: url(' + this.src + ');' + 
        'width:' + this.width + 'px;' + 
        'height:' + this.height + 'px;' ,
        class: 'fakeImg'
    })
})

Exemplo online: https://jsfiddle.net/dife/t53as464/1/

 

Link para o comentário
Compartilhar em outros sites

@DiF Esse código eu peguei pronto e adaptei.

Eu ia usá-lo, porque ele permite carregar qualquer tamanho de imagem. O setor aqui da empresa que vai usar, não quer se preocupar em diminuir as imagens para postar. Querem que seja tudo automático, tipo, descarregar da câmera e postar. Esse foi o único que encontrei nas buscas que fiz. 

Mas vou seguir o que você me passou, para não perder qualidade, senão ficarão muito ruins as imagens no site.

Vou modificar o código e qualquer dúvida, eu volto a postar!

Obrigada!

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Moderador

@Gisele Passoni Entendo.  No caso as vezes compensa usar um redimensionador... quando se precisa que todas as imagens tenham exatamente o mesmo tamanho mas tem vezes( seu caso) que a qualidade cai, talvez por uma limitação do plugin ou erro dele. Como é pronto não tem como analisar tudo, alias é inviável analisar um plugin pronto.

 

Por isso a minha sugestão é que você simplifique e defina um limite na imagem via CSS!   assim se um usuário fizer um upload de uma imagem em 1920x1080 ou em 600x800 ou simplesmente um 300x300 , a imagem que aparecerá terá o limite que você definiu no CSS, aí usando as dicas que dei acima, você consegue manter a proporção da imagem sem estica-la ou achata-la! :thumbsup:

 

O ideal é que você coloque um aviso de uso:  por exemplo : O anexo aqui do editor do fórum tem instruções de tamanho total de 14,65Mb e os tipos de arquivos suportados. 

 

Você poderia por o mesmo ao lado do upload informando um tamanho "preferêncial"  que fique boa as imagens. Ou seja, uma sugestão. Claro que o usuário pode decidir se envia uma imagem no tamanho recomendado, ou uma maior.  Se caso ele enviar uma maior, quem vai limitar a imagem será o CSS! OU o jQuery(segundo exemplo)

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...