Создание фильтров изображений в стиле Instagram.
В этом уроке мы сделаем небольшое веб-приложение, которое позволяет перетаскивать изображения с компьютера в окно браузера и применять к нему фильтры в стиле инстаграм. Для реализации этого мы будем использовать несколько JavaScript библиотек и плагинов.
- Caman.js — библиотека для управления элементом canvas, которая позволяет накладывать разные фильтры на изображения. Доступно 18 фильтров, которые мы будем использовать в примере (но вы можете создать больше).
- Filereader.js — небольшая библиотека, обрабатывающая события HTML5 drag/drop и упрощающая работу с ними.
- jQuery Mousewheel — используется для прокрутки списка фильтров.
- также мы используем последнюю версию jQuery.
HTML разметка фильтров
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Instagram-like Filters with jQuery | Easy-Code.ru Demo</title> <link href="assets/css/style.css" rel="stylesheet" /> <!-- Include the Yanone Kaffeesatz font --> <link href="http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz:400,200" rel="stylesheet" /> </head> <body> <h1>Instagram <b>Filters</b></h1> <div id="photo"></div> <div id="filterContainer"> <ul id="filters"> <li> <a href="#" id="normal">Normal</a> </li> <li> <a href="#" id="vintage">Vintage</a> </li> <li> <a href="#" id="lomo">Lomo</a> </li> <li> <a href="#" id="clarity">Clarity</a> </li> <li> <a href="#" id="sinCity">Sin City</a> </li> <!-- 14 More filters go here --> </ul> </div> <!-- Libraries --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <script src="assets/js/filereader.min.js"></script> <script src="assets/js/caman.full.js"></script> <script src="assets/js/jquery.mousewheel.min.js"></script> <script src="assets/js/script.js"></script> </body> </html>
Помимо библиотек и плагинов, перечисленных выше, мы будем использовать файл script.js (о нем мы поговорим ниже). Также в заголовке страницы мы подключаем шрифт Yanone Kaffeesatz.
JavaScript/jQuery
Для того, что бы заставить наше приложение работать, необходимо выполнить несколько шагов:
- Принять изображение, которое перетащили в окно браузера;
- Создать элемент canvas размером 500×500 (можно изменить) и сохранить его в памяти;
- Отслеживать клики на фильтрах. Когда какой-либо выбран:
- Создать копию элемента canvas;
- Удалить элементы canvas на странице;
- Добавить копию canvas к элементу #photo;
- Если выбран фильтр, отличный от “Normal”, применить библиотеку Caman;
- Добавить к выбранному фильтру класс “active”.
- Применить фильтр “Normal”
Код assets/js/script.js
$(function() {
var maxWidth = 500,
maxHeight = 500,
photo = $('#photo'),
originalCanvas = null,
filters = $('#filters li a'),
filterContainer = $('#filterContainer');
// используем плагин fileReader для отслеживания
// событий drag and drop элемента photo:
photo.fileReaderJS({
on:{
load: function(e, file){
// перетащили изображение.
var img = $('<img>').appendTo(photo),
imgWidth, newWidth,
imgHeight, newHeight,
ratio;
// удаление элементов canvas
// удаление обработки предыдущих изображений.
photo.find('canvas').remove();
filters.removeClass('active');
// если изображение успешно загружено,
// узнаем его ширину и высоту:
img.load(function() {
imgWidth = this.width;
imgHeight = this.height;
// выясняем, поместится ли изображение в выделенные рамки
if (imgWidth >= maxWidth || imgHeight >= maxHeight) {
// изображение слишком большое,
// максимальный размер - 500x500
if (imgWidth > imgHeight) {
// широкое
ratio = imgWidth / maxWidth;
newWidth = maxWidth;
newHeight = imgHeight / ratio;
} else {
// высокое или квадрат
ratio = imgHeight / maxHeight;
newHeight = maxHeight;
newWidth = imgWidth / ratio;
}
} else {
newHeight = imgHeight;
newWidth = imgWidth;
}
// создание элемента canvas.
originalCanvas = $('<canvas>');
var originalContext = originalCanvas[0].getContext('2d');
// поместим canvas в центр
originalCanvas.attr({
width: newWidth,
height: newHeight
}).css({
marginTop: -newHeight/2,
marginLeft: -newWidth/2
});
// нарисовать изображение в canvas
// с новыми размерами
originalContext.drawImage(this, 0, 0, newWidth, newHeight);
// больше изображение не пригодится
img.remove();
filterContainer.fadeIn();
// применение фильтра "normal"
filters.first().click();
});
img.attr('src', e.target.result);
},
beforestart: function(file){
// Разрешить только изображения.
return /^image/.test(file.type);
}
}
});
// отслеживание кликов по фильтрам
filters.click(function(e){
e.preventDefault();
var f = $(this);
if(f.is('.active')){
// если фильтр уже активен
return false;
}
filters.removeClass('active');
f.addClass('active');
// копируем canvas
var clone = originalCanvas.clone();
// копируем изображение, хранящееся в canvas
clone[0].getContext('2d').drawImage(originalCanvas[0],0,0);
// добавим копию на страницу и применим
// к ней библиотеку Caman
photo.html(clone);
var effect = $.trim(f[0].id);
Caman(clone[0], function () {
// если фильтр существует, применим его:
if( effect in this){
this[effect]();
this.render();
}
});
});
// использование плагина mousewheel
// для прокрутки списка фильтров
filterContainer.find('ul').on('mousewheel',function(e, delta){
this.scrollLeft -= (delta * 50);
e.preventDefault();
});
});
Готово!
Данный пример будет работать в браузерах, которые поддерживают drag/drop. Некоторые фильтры требуют сложных вычислений, поэтому могут быть небольшие задержки перед отображением результата. Мы ограничили размер изображения 500 пикселями, но вы можете изменить это значение, как хотите.








Здравствуйте! Помогите разобраться с этой библиотеке. Где можно найти эту библиотеку с описаниями всех функций??
Скажите, а как затем все это дело соханить через PHP в БД и на диск уже преобразованный файл?
Здравствуйте!
Что бы сохранить изображение на сервере понадобится добавить js код в index.html сразу после подключения всех библиотек:
<script type="text/javascript"> $(document).ready(function () { $("#download").click(function(e){ $('canvas').attr('Id', 'can'); var canvas = document.getElementById('can'); if (canvas == null) { alert('You should drop your Image!'); return false; } var data = canvas.toDataURL(); $.post('save.php', { 'data' : data }); }); }); </script>Так же надо добавить ссылку с id=»download»:
В фале save.php примерно следующее:
$data = $_REQUEST['data']; file_put_contents('image.png', base64_decode(substr($data, strpos($data, 'base64') + 7)));Все получилось, но нужно еще как-то сделать, чтобы файлы открывались не посредством дропа, а кликом например по ссылке. Это возможно? Если да, то как примерно?
Для этого можно использовать плагин Colorbox. Подключение плагина:
<script src="assets/js/jquery.colorbox-min.js"></script>Разметка:
<a class="links" id="view" href="#view_img">Показать изображение</a> <div style="display:none"> <div id="view_img"> <img width="500" height="500" id="view_src" src="" alt=""/> </div> </div>Активация плагина:
$("#view").colorbox({ inline: true, href: "#view_img", fastIframe: false, onLoad : function() { var canvas = document.getElementById('can'); if (canvas == null) { alert('You should drop your Image!'); return false; } var data = canvas.toDataURL(); document.getElementById("view_src").src = data; } });При нажатии на ссылку #view изображение будет показано в всплывающем окне. Я добавил эту возможность в пример этого урока, можете посмотреть как это работает.
Я решил попробовать сделать не так, а чтобы открывалось в новой ссылке:
function editImage(elem, id){
if(id == null){
alert(‘No image’);
return false;
}
/* Здесь как-то надо передать elemet (является прямой ссылкой на изображение) в canvas.toDataURL();, чтобы все прошло успешно */
}
Я много чего перепробовал, но ничего не выходит. Пример отправляющей функции выглядит как-то так:
onclick=»editImage(‘image.gif’, ‘1’); return false;»
Но вот беда, не выходит все это.
И кстати, не подскажете, как очищать элемент canvas.toDataURL(); от изображения?
А как можно сделать такое … Вот я вставил картинку , профильтровал ее. Как сделать так что бы ее отправить в PHP файл и там уже загрузить на сервер ? Мне нужно знать как это сделать в jquery
Как сделать все это без драгндроп? Просто прописав путь к картинке? Не выходит.