Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поворот изображений без потери качества, just for fun, чистый js, специфично... 
:(
    Опции темы
RESIN
  Дата 16.1.2012, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 8.10.2010

Репутация: нет
Всего: нет



Долго свербило, написал следующую функцию:

Код

function fRotate (source, handleCanvas, angle) {

  var sourceWidth=source.width+2, sourceHeight=source.height+2;

  var sourceCanvas=document.createElement('canvas');
  sourceCanvas.width=sourceWidth;
  sourceCanvas.height=sourceHeight; 
  var sourceContext=sourceCanvas.getContext('2d');
  sourceContext.drawImage(source, 1, 1);
  var sourceData=sourceContext.getImageData(0, 0, sourceWidth, sourceHeight);
  var sourcePixels=sourceData.data;


  var diagonal=Math.floor(Math.sqrt(sourceWidth*sourceWidth+sourceHeight*sourceHeight));
  var handleWidth=diagonal, handleHeight=diagonal;


  handleCanvas.width=handleWidth;
  handleCanvas.height=handleHeight;
  var handleContext=handleCanvas.getContext('2d');
  var handleData=handleContext.getImageData(0, 0, handleWidth, handleHeight);
  var handlePixels=handleData.data;


  var sin=Math.sin(angle), cos=Math.cos(angle);

  var i=0,
  sx, sy, dx, dy, ddx, ddy, dxdy, dxddy, ddxdy, ddxddy,
  m, n, o, p, swwww=sourceWidth*4,
  r, g, b, a;

  var
  syr=(sourceHeight-(cos+sin)*diagonal)/2,
  sxr=(sourceWidth+(sin-cos)*diagonal)/2,
  widthsin=diagonal*sin,
  widthcos=diagonal*cos;

  for (var y=0; y<diagonal; y+=1) {
    syr+=cos;
    sxr-=sin;
    for (var x=0; x<diagonal; x+=1) {
      i+=4;
      syr+=sin;
      sxr+=cos;
      if ((syr>-1) && (syr<sourceHeight) && (sxr>-1) && (sxr<sourceWidth)) {

        dx=sxr%1;
        ddx=1-dx;
        sx=sxr-dx;

        dy=syr%1;
        ddy=1-dy;
        sy=syr-dy;

        dxdy=dx*dy;
        dxddy=dx*ddy;
        ddxdy=ddx*dy;
        ddxddy=ddx*ddy;

        m=sx*4+sy*swwww;
        n=m+4;
        o=m+swwww;
        p=o+4;

        r=sourcePixels[m  ]*ddxddy+sourcePixels[n  ]*dxddy+sourcePixels[o  ]*ddxdy+sourcePixels[p  ]*dxdy;
        g=sourcePixels[m+1]*ddxddy+sourcePixels[n+1]*dxddy+sourcePixels[o+1]*ddxdy+sourcePixels[p+1]*dxdy;
        b=sourcePixels[m+2]*ddxddy+sourcePixels[n+2]*dxddy+sourcePixels[o+2]*ddxdy+sourcePixels[p+2]*dxdy;
        a=sourcePixels[m+3]*ddxddy+sourcePixels[n+3]*dxddy+sourcePixels[o+3]*ddxdy+sourcePixels[p+3]*dxdy;

        handlePixels[i  ]=r-(r%1);
        handlePixels[i+1]=g-(g%1);
        handlePixels[i+2]=b-(b%1);
        handlePixels[i+3]=a-(a%1);

      }
    }
    syr-=widthsin;
    sxr-=widthcos;
  }

  handleContext.putImageData(handleData, 0, 0);

}


Поворачивает изображение source на угол angle и выводит на канву handleCanvas. Качество сохраняет. Итоговая канва будет квадратной со стороной = длине диагонали исходного изображения.

Работает функция медленно, что и ожидал, писал ее больше из интереса. Подходит разве что для разового поворота, не для анимации. Проверял в гуглохроме, опере и файерлисе., в ИЕ не работает, т.к. нет объекта канвы.

После оптимизаций код стал совсем некомментируемым, по-этому извините, без комментариев... Во вложении - пример с использованием + в index.html закоменчены промежуточные состояния циклов построения повернутого изображения...

Если кто сможет подсказать, как обращаться к пикселям img без помощи canvas, и выводить в img, буду благодарен!

Добавил: Пример во вложении работает на виртуальной машине, а если запускать как файл, то браузер (точнее javascript) не сможет получить путь к изображению r.png., чтобы работало, укажите в строке #112 вместо 'r.png' какой-либо реальный url к не оч. большому, существующему изображению.

Это сообщение отредактировал(а) RESIN - 17.1.2012, 06:54

Присоединённый файл ( Кол-во скачиваний: 11 )
Присоединённый файл  rotatescript.zip 159,46 Kb
PM MAIL   Вверх
RESIN
Дата 17.1.2012, 05:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 8.10.2010

Репутация: нет
Всего: нет



Уважаемые модераторы, обычно на форумах правила раздела публикуются в специальную закрепленную тему с пометкой "важное". Здесь не так, по-этому пока я не создал эту тему, я не знал, что:

"Здесь публикуют скрипты, которые уже проверены в обсуждениях других тем (при этом полезно поставить ссылки на все смежные обсуждения) или переносятся кем-либо из модераторов по просьбе участников, если видно, что в результате обсуждения темы был написан полезный или интересный скрипт. Третий возможный вариант - участник форума публикует скрипт, заведомо известный как полезный и эффективный, для, возможно, небольшой доработки и обсуждения."

Должно быть, эту тему нужно перенести в более соответствующий раздел. Будьте добры, пожалуйста...
PM MAIL   Вверх
Google
  Дата 21.9.2017, 09:53 (ссылка)  





  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Здесь публикуют скрипты, которые уже проверены в обсуждениях других тем (при этом полезно поставить ссылки на все смежные обсуждения) или переносятся кем-либо из модераторов по просьбе участников, если видно, что в результате обсуждения темы был написан полезный или интересный скрипт. Третий возможный вариант - участник форума публикует скрипт, заведомо известный как полезный и эффективный, для, возможно, небольшой доработки и обсуждения.
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Наши скрипты | Следующая тема »


 




[ Время генерации скрипта: 0.0522 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.