Как перевернуть определенные изображения перед добавлением на сервер?

208
10 декабря 2017, 13:11

Есть форма добавления поста, к посту будут прикреплены картинки. Вот перед отправкой этого поста в БД необходимо просмотреть загруженные картинки и если что их повернуть, а потом уже нажать на кнопку "Отправить". Никак не могу найти готового решения. В загрузчике мне нужны только превьюшки и поворот. Может у кого есть примеры готовых реализаций? Хотя бы понять архитектуру и как это лучше организовать

Сейчас у меня стоит такой загрузчик с превmюшками

<iframe class="fileupload pos-rel" frameborder="0" scrolling="no" src="{%$settings.path%}ajaxfileupload_i/?field_key={%$field_key%}&file={%$field.file%}" ></iframe>
  <script>
     $(document).ready(function() {   
     $('#{%$field_key%}').uploadify({
     'uploader'  : '{%$settings.path%}js/uploadify/uploadify.swf',
     'buttonImg' : '{%$settings.path%}imgtext.png',
     'height'      : 18,
     'weight'      : 200,
     'wmode'       : 'transparent',
     'script'    : '{%$settings.path%}uploadify/',
     'cancelImg' : '{%$settings.path%}js/uploadify/cancel.png',
     'fileExt'   : '{%foreach from=$field.values_array item='vl' name='ii'%}*.{%$vl%}{%if $smarty.foreach.ii.last eq false %};{%/if%}{%/foreach%}',
     'fileDesc'    : '{%foreach from=$field.values_array item='vl' name='ii'%}{%$vl%}{%if $smarty.foreach.ii.last eq false %}, {%/if%}{%/foreach%}',
     'multi'     : false,
     'auto'      : true,
     'sizeLimit'   : {%$field.max%}000,  //in bytes
     'scriptData'  : {'field_id':{%$field.id%}, 'form_id':form_id},
     'onComplete': function (event, queueID, fileObj, response, data){
     if(response != 'error'){
     $('#h1-{%$field_key%}').show('fast');
     $('#i-{%$field_key%}').attr('src', response);                                       
     $('#h2-{%$field_key%}').show('fast');                                       
     }                            
     } 
     });    
      });   
  </script>
Answer 1

Мне кажется, что надо подойти с другой стороны:

На стороне клиента дать пользователю манипулировать с изображением (на уровне превьюшек или с цельным изображением, не суть):

  1. показывать изображение
  2. повернуть на 90 градусов по часовой
  3. повернуть на 90 градусов против часовой
  4. отразить по горизонтали
  5. отразить по вертикали

при каждом воздейсткии на изображение (2-5) (например, при нажатии на соответствующую кнопку) рассчитывать итоговую трансформацию.

Итоговая трансформация изображения с помощью любого кол-ва действий 2-4 сводится к 3 операциям:

  1. повернуть изображение по часовой стрелке на 0, 90, 180, 270 градусов
  2. отразить по горизонтали (да/нет)
  3. отразить по вертикали (да/нет)

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

В итоге будет только 1 перезапись файла и в случае jpeg качество от повторного сжатия просядет незначительно

На клиенте с помощью данных об итоговой трансформации манипулировать изображением через css и transform. Например можно просто создать несколько классов например: .r0, .r90, .r180, .r270, .fh, .fv (rotate & flip) и выставлять их изображению с нужными данными об итоговой трансформации.

Answer 2

imagerotate — Поворот изображения с заданным углом.

Пример #1 Поворот изображения на 180 градусов

Этот пример поворачивает изображения на 180 градусов - верхом вниз.

    <?php
// Файл и угол поворота
$filename = 'test.jpg';
$degrees = 180;
// Тип содержимого
header('Content-type: image/jpeg');
// Загрузка изображения
$source = imagecreatefromjpeg($filename);
// Поворот
$rotate = imagerotate($source, $degrees, 0);
// Вывод
imagejpeg($rotate);
// Высвобождение памяти
imagedestroy($source);
imagedestroy($rotate);
?>
Answer 3

Код воспроизводимый, на стили не отвлекался.

  <input type="file" id="fileInput">
    <button type="button" id="loadImgBtn">Загрузить фото</button>
    <div id="previewFoto">
        <button type="button" id="rotateBtn">Повернуть на 90 градусов</button>
    </div>
    <div id="rezultImg">
        <button type="button" id="rezultBtn">Итоговая картинка</button>
    </div>

Js

 var fileInput = document.getElementById("fileInput");
    var loadImgBtn = document.getElementById("loadImgBtn");
    var previewFoto = document.getElementById("previewFoto");
    var rotateBtn = document.getElementById("rotateBtn");
    var rezultBtn = document.getElementById("rezultBtn");
    var x = 200;
    var y = 300;
    function loadFoto(arg){
            var read = new FileReader();
            read.readAsDataURL(arg);
            read.onload = function(){
                var t = read.result;
                var img = new Image();
                img.src = t;
                //нужно установить небольшую задержку, т.к. фото не успевает загрузится
                setTimeout(function(){
                var canvas = document.createElement("canvas");
                canvas.id = "canvas";
                canvas.setAttribute("width", x);
                canvas.setAttribute("height", y);
                var ctx = canvas.getContext("2d");
                ctx.beginPath();
                ctx.drawImage(img,0,0,x,y)
                ctx.closePath();
                previewFoto.appendChild(canvas);
            },30)
            }
    }
    loadImgBtn.onclick = function() {
        loadFoto(fileInput.files[0]);
    }
    rotateBtn.onclick = function(){
        var canvasImg = canvas.toDataURL("image/jpeg");
        var img = new Image();
        img.src = canvasImg;
        setTimeout(function(){
            var canvas = document.getElementById('canvas');
            var context = canvas.getContext("2d");
            context.beginPath();
            //устанавливаем точку, вокруг которой будет вертется картинка (центр)
            context.translate(100,150);
            //rotate устанавливается в радианах. 1 радиан = 180/Пи
            context.rotate(Math.PI);
            context.drawImage(img,-100,-150,x,y);
            context.closePath();
        },30)
    }
    rezultBtn.onclick = function(){
        var canvas = document.getElementById("canvas");
        var canvasImg = canvas.toDataURL("image/jpeg");
    //здесь можно разместить код отправки изображения на сервер
        var rezultImg = document.getElementById("rezultImg");
        var img = new Image();
        img.src = canvasImg;
        rezultImg.appendChild(img);
    }

Код содержит небольшой баг, связанный с повторным нажатием на кнопку поворота. Но у меня уже нет сил его править)

READ ALSO
Почему не работает оповещение?

Почему не работает оповещение?

Код успешно выводит в консоль нужный мне текстНо на примере я попытался реализовать оповещение на тот случай, если переменная n имеет хотя...

204
Удалить строку из таблицы

Удалить строку из таблицы

Из базы данных генерируется html-таблица с такими же полямиПри нажатии на строку таблицы в javascript меняется её цвет (становится активной)

269
Ошибка Uncaught TypeError: Cannot read property &#39;concat&#39; of undefined

Ошибка Uncaught TypeError: Cannot read property 'concat' of undefined

Всем привет, у меня такая проблема, пишу приложение на Cordova + Jquery 32

269
Как парсить записи группы VK php? [требует правки]

Как парсить записи группы VK php? [требует правки]

Нужно парсить записи группы ВК на PHPИскал решения

214