webew
Войти » Регистрация
 
JavaScript :: Координаты, размеры, ресайз, drag_and_drop

Crop и Resize ваших изображений

5 июня 2008, 14:17

Зачем?

Задача была сделать универсальный, по-возможности, скрипт, который мог бы заниматься ресайзом (изменением размеров) и кропом (обрезанием) любых изображений. Это иногда бывает нужно:
  • для "умного" вырезания превью из большого изображения,
  • для подготовки аватара из любой загруженной фотки,
  • ну и мало ли еще зачем нужен кроп и ресайз :-)
Cropresizer example
Смотрим как оно выглядит и работает.

Установка

Скачайте архив fc-cropresizer.zip (97Кб) и распакуйте в нужную директорию. Не пугайтесь большому размеру дистрибутива, там в папке demo-photo находятся изображения, которые можно смело удалять после просмотра демки.

Кроме папки с фотками в распакованном архиве вы найдете:

  • папку imgcropresize — включает пару мелких изображений непосредственно для кроп-ресайза;
  • demo.html — та самая демка;
  • fc-cropresizer.css — стили;
  • fc-cropresizer.js — движок;
  • LICENSE — лицензию BSD;

Подключайте в <HEAD> js- и css-файлы, кладите куда нужно папку с изображениеми и начинаем!

Использование

В любом удобном месте (head или body - не важно) пишем небольшой JavaScript-сценарий, для инициализации кропресайза:
cropresizer.getObject("photo1").init({
    cropWidth : 150,
    cropHeight : 150,
    onUpdate : function() {}
});

cropresizer — это используемый namespace. Методу getObject передается в качестве параметра идентификатор (id) изображения, а метод init в качестве единственного аргумента принимает объект в JSON-формате, свойства которого настроят необходимым образом кроп-ресайз. Рассмотрим эти свойства:
  • cropWidth — по-умолчанию равен 100, задает длину области кропа в пикселях.
  • cropHeight — то же самое для высоты.
  • onUpdate — единственное обязательное свойство (точнее метод). Принимает в качестве значения функцию, которая через this имеет доступ ко всем свойствам объекта кроп-ресайза. В третьем примере демки все необходимые данные выводятся в завершающий страницу текстовый блок. Этот метод жизненно необходим для сохранения того, что вы наменяли, обычно в hidden-поля формы.

Размеры изображения можно изменять с сохранением пропорции width/height (по-умолчанию), так и без сохранения, для чего нужно выставить свойство saveProportions : false.

Остановимся более подробно на механизме работы скрипта, чтобы осветить некоторые полезные моменты:

  1. Скрипт получает элемент по идентификатору и заключает его в контейнер (DIV) фиксированных размеров. Таким образом, при уменьшении размеров изображения весь нижеидущий HTML-контент не едет, а остается на месте. Эту возможность можно отключить установив свойство this.withContainer : false.
  2. Как вы знаете, если зажать левую кнопку мыши и перемещать указатель, то сожержимое страницы будет выделяться, что не очень полезно при кропе/ресайзе. Чтобы забороть этот эффект вся страница накрывается прозрачной абсолютно-спозиционированной "пленкой" с z-index:100, которая препятствует выделению. Однако, эта пленка мешает кликать по ссылкам на странице, поэтому либо необходимо поднимать ссылки, либо отключить пленку опцией this.stopSelection : false. Также можно использовать привычные но невалидные onSelectStart="return false;" для IE и -moz-user-select:none для Gecko.
  3. Можно изменить фон области кропа (по-дефолту белый) или отключить показ размера кропа опциями cropBackground и showCropSize соот-но.

Кроссбраузерность

Работоспособность скрипта проверена в: - IE6, IE7 - WIN;
- FF1.5, FF2 - WIN;
- Mozilla 1.7.1 - WIN;
- Safari 3 WIN;
- Opera 9+ WIN, однако, наблюдается выделение контента, не смотря на защитную "пленку";
- FF2 NIX;
- Opera NIX;

В старых (ниже девятой) версиях Оперы проблемы. Буду бороть.

Future

  • Сделать возможность ресайза области кропа
  • Проработать ресайз изображения в сторону увеличения
  • То, что вы предложите :-)

© Все права на данную статью принадлежат порталу webew.ru. Перепечатка в интернет-изданиях разрешается только с указанием автора и прямой ссылки на оригинальную статью. Перепечатка в печатных изданиях допускается только с разрешения редакции.
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
NO USERPIC

FX Poster

У тебя "поехала" кодировка в RSS.
05.06.2008, 21:09
Ответить

bur

Спасибо, починили.
05.06.2008, 21:44
Ответить

1234ru

Вещь оч. крутая имхо. Спасибо.
Очень будет полезна при загрузке аватар и т.п.

Такой вопрос: как конкретно происходит изменение размеров картинки?
Точнее, тут даже важен не весь вопрос в целом, а подвопрос, в нем содержащийся: не проиграют ли по качеству люди, совершающие ту же операцию в каком-нибудь графическом редакторе (скажем, в Photoshop)?

(я так понимаю, за это отвечает сторонняя библиотека)
То, что не убивает нас, делает нас инвалидами.
07.06.2008, 04:39
Ответить

bur

Сам скрипт занимается простым изменением размеров изображения с помощью style.width и style.height. У JavaScript-а нет практической возможности заниматься полноценным ресайзом и отдавать бит-поток для сохранения готового изображения. Но, зато он может отдать любые координаты и размеры после изменения, например такой набор: newWidth, newHeight, cropTop, cropLeft, corpWidth, cropHeight. Этого вполне хватить для качественной обработки фотографий на сервере. Например, с помощью функции imageCopyResampled в PHP (при подключенном GD-модуле).
07.06.2008, 07:35
Ответить
NO USERPIC

wolfich

А можно пример накидать для передачи в POST?
15.10.2008, 00:13
Ответить

bur

Пусть у вас есть форма (пост или гет, не важно) с четырьмя хидден-полями:

<form id="formId" action="#">
     <input type="hidden" name="x" value="0" />
     <input type="hidden" name="y" value="0" />
     <input type="hidden" name="w" value="0" />
     <input type="hidden" name="h" value="0" />
</form>


X и Y - это координаты верхнего левого угла области кропа.
W и H - это длина и высота области кропа.

Тогда, чтобы в хидден-поля записывались данные о текущем состоянии кропа, в методе onUpdate пишем такой скрипт:

onUpdate : function() {
    var form = document.getElementById("formId");
    if (form) {
        form.w.value = this.cropWidth;
        form.h.value = this.cropHeight;
        form.y.value = (this.cropTop - this.iTop);
        form.x.value = (this.cropLeft - this.iLeft);
    }
}


Как-то так. Не проверял, но должно работать.
15.10.2008, 13:18
Ответить
NO USERPIC

wolfich

Благодарю, очень даже работает :)
15.10.2008, 16:27
Ответить

Taypfoon

Уважаемый, а не будете ли Вы столь добры, чтобы ознакомить общественность с готовым рабочим вариантом реализации
Я так понял Вам удалось по приложенным здесь данным сделать crop и сохранить его в файл...
Поделитесь с дилетантом если не секретно :)
Всё гениальное просто :)
12.10.2009, 22:52
Ответить
NO USERPIC

killest

а всё-таки :)

вопрос о неприличном поведении в Firefox3 остаётся открытым?
После первого перемещения кропа и mouseup он не перетаскивается кроме как с предварительным ресайзом или добавочным кликом по нему :(
Что не может не огорчать...
09.09.2008, 13:16
Ответить

bur

Спасибо за репорт! Обязательно починю.
09.09.2008, 19:55
Ответить
NO USERPIC

killest

в общем, это проблема некорректного mouseup'а у FF3
решается даже так:
src

this.addHandler(document, "mouseup", function () {

_this.cropMoveState = false;

_this.resizeMoveState = false;

_this.redefine();

_this.resize.focus();
09.09.2008, 20:42
Ответить
NO USERPIC

wolfich

Однако, бага. Если cropWidth != cropHeight, т.е. область кропа прямоугольная, то при ресайзе исходной картинки до размера, меньшего чем кроп, координаты кропа становятся отрицательными и кроп уползает из div'а :(
16.10.2008, 14:44
Ответить

bur

Спасибо за репорт!
Буду фиксить.
16.10.2008, 16:17
Ответить
NO USERPIC

add

Спасибо за библиотечку. Очень понравилось.

Позвольте добавить пожелание для будущих версий:

ввести метод обратный init (какой-нибудь destroy). Хочется создавать и убирать диалоги crop-a при необходимости, а не только создавать по domReady.
13.11.2008, 14:48
Ответить
NO USERPIC

LZD

раз уж этот скрипт распространяется бесплатно..нельзя ли подсказать как можно сделать изменяемую область кропа..очень нужно
09.02.2009, 20:18
Ответить

bur

Скрипт распространяется бесплатно, но пишется только одним человеком - мной.
Краткого совета дать не получится, нужно сесть и написать этот кусок кода...
10.02.2009, 18:22
Ответить
NO USERPIC

LZD

спасибо, уже разобралась..маленько не так получилось..но работает
13.02.2009, 11:07
Ответить

Taypfoon

Хорошее творение :) СПАСИБО !
Хорошо бы добавить поворот картинки для модернизации скрипта.
Вот бы еще простыми словами или примером объяснили как сохранить выделенную область в файл добавив в demo.html
форму для загрузки картинки и кнопку сохранения на сервер. Было б супер ! Вот так например http://www.gorlovka.org.ua/1/demo.html


Всё гениальное просто :)
01.10.2009, 23:51
Ответить

bur

Taypfoon
Вот бы еще простыми словами или примером объяснили как сохранить выделенную область в файл

Посмотрите вот этот комментарий.

Taypfoon
Хорошо бы добавить поворот картинки для модернизации скрипта.

В принципе осуществимо, я подумаю :-)
02.10.2009, 11:37
Ответить

Taypfoon

Это я видел. Но довольно сложно для понимания не программистом (а я не программист). Думаю со мной согласятся многие, что готовое решение с наглядным примером было бы приятней. Вы ведь сделали наглядный пример а не выложили просто код своего скрипта :)
Всё гениальное просто :)
03.10.2009, 12:27
Ответить

bur

В комментарии, на который я дал ссылку, пример и так нагляднее некуда. А сама процедура изготовления превью происходит уже на сервере и никакого отношения к JavaScript не имеет.
04.10.2009, 12:23
Ответить

mi.rafaylik

С Новым Годом ребята! )
Подскажите плиз, как подключить скрипт для любого изображения, которое содержится в родительском div, чтоб не инициировать каждое изображение по его id? например:
<div id="content">
<img src="1.jpg">
<img src="2.jpg">
</div>
То есть вместо getElementById (по id) брать по типу элемента (по img). Сам попробовал, не получилось
31.12.2012, 19:04
Ответить

1234ru

Похоже, библиотека рассчитана только на передачу id.
В противном случае нужно переписывать ее код (глянул его бегло - быстро переписать не получится, нужно разбираться).
То, что не убивает нас, делает нас инвалидами.
05.01.2013, 03:48
Ответить

mi.rafaylik

Жалко.
Ещё у данного скрипта заметил минус - использование getObject, который (если верить Microsoft) не поддерживается в IE9 и IE10 :/
Хотя я уже нашёл подобное решение (только для handler resize без crop) на jQuery на 31 строку кода. Оно точно кроссбраузерное )
05.01.2013, 03:58
Ответить
NO USERPIC

baphometh

Не получается повесить на картинку добавленную в страницу с помощью ajax =\
Это тоже невозможно?
23.06.2013, 03:18
Ответить

1234ru

Сложно сказать, надо смотреть код библиотеки
(разработчик перестал ее поддерживать, так что спросить у него не получается).
То, что не убивает нас, делает нас инвалидами.
24.06.2013, 13:09
Ответить
NO USERPIC

baphometh

Цитата:
разработчик перестал ее поддерживать


Очень жаль :(
Было бы здорово, если бы кто-нибудь взялся переписать под современные браузеры как плагин для jquery.
Потому что по функционалу это самое оптимальное решение из тех что я нашел (для аватар и т.д.)
Плохо, что у меня знаний не хватает =\

Все что гуглится из аналогов либо без "ресайза", либо какие-то монстры которые даже jquery не обходятся
24.06.2013, 19:08
Ответить
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
© 2008—2024 webew.ru, связаться: x собака webew.ru
Сайт использует Flede и соответствует стандартам WAI-WCAG 1.0 на уровне A.
Rambler's Top100

Реклама: