Advanced Thumbnail Creator
10.03.20231 Задача
Работая с новостными лентами или же просто с информацией, содержащей графические изображения, довольно часто возникает потребность генерации картинок-превью. На первый взгляд нет ничего проще чем создать уменьшенное изображение произвольного рисунка или фотографии. Однако, оказывается и в этой области есть где развернуться.
2 Существующие решения
Есть несколько способов решения данной задачи:
- ?спользование оригинального изображения в качестве превью путем его уменьшения свойствами тега .
- Уменьшение размеров изображения при помощи функций imagecopyresampled(), imagecopyresized() библиотеки GD.
- Выделение центральной области изображения и ее последующее преобразование функциями библиотеки GD.
- Создание превью при помощи графических приложений на локальной машине и последующая загрузка на сервер.
Очевидное преимущество первых трех методов — полная автоматизация процесса. Недостатки: в первом случае изображение загружается в оригинальном размере (рис. 2а), во втором - в превью не сохраняются оригинальные пропорции изображения (рис. 2б), в третьем - центральная часть изображения не всегда является "значащей" (рис. 2в).
Четвертый способ генерации превью дает необходимые результаты (рис. 2г), но добавляет лишние хлопоты при переключении между приложениями, возникает необходимость загрузки двух файлов вместо одного (в лучшем случае).
Рисунок 1 — ?сходное изображение
рис.2а |
рис.2б |
рис.2в |
рис.2г |
Рисунок 2 — Результаты генерации превью (70x70)
3 Решение
Суть метода — автоматическое создание превью с помощью php-скрипта посредством ручного выделения "значащей" области.
4 ?спользуемые технологии
PHP, Javascript, DOM, CSS, HTML
5 Кросс-браузерность
Internet Explorer 6.0,7.0; FireFox 1.0,2.0; Opera 9.0; Safari 2.0;
6 Входные и выходные параметры
Входные параметры:
- $_GET[filename] — строка, определяющая имя файла и путь к нему относительно корневого каталога на сервере. Переменная $_GET[filename] должна быть предварительно закодирована функцией urlencode();
- $_GET[thumbwidth] — предустановленная ширина превью изображения. Если этот параметр равен "0" или не определен, ширина превью определяется в зависимости от выбранной области.
- $_GET[thumbheight] — предустановленная высота превью изображения. Если этот параметр равен "0" или не определен, высота превью определяется в зависимости от выбранной области.
Выходные параметры:
- Превью изображения на странице браузера.
- Файл-превью типа JPEG, находящийся в том же каталоге что и исходное изображение.
7 Реализация
Разработанный программный комплекс состоит из двух файлов.
- thumbcreate.js — набор функций для работы с выделяемой областью и функции подготовки генерации изображения.
- thumbcreate.php — содержит функцию генерации превью, блок отображения рабочей области и форму ввода-вывода параметров превью.
7.1. Описание функций модуля thumbcreate.js.
//initialization
function init()
{
document.getElementById("image").onclick=mouseHandler;
document.getElementById("image").onmousemove=mouseHandler;
document.getElementById("th_w").value=thumbWidth;
document.getElementById("th_h").value=thumbHeight;
}
//mouse handler
function mouseHandler(mouseEvent)
{
if (!mouseEvent) mouseEvent = window.event;
if (mouseEvent.button == 2) return;
var element = (mouseEvent.target)?mouseEvent.target:mouseEvent.srcElement;
//for a clique we begin to draw a selection rectangle
if (mouseEvent.type=="click")
{
var x = mouseEvent.clientX - document.getElementById("image").offsetLeft;
var at = mouseEvent.clientY - document.getElementById("image").offsetTop;
pointSet(x,y);
rectangleDraw("area");
};
//draw the selection region during mouse motion
if (mouseEvent.type=="mousemove")
{
.
}
}
//setting coordinates for top left and right bottom corner
function pointSet(x,y)
{
if (!ptype)
{
x1=x+document.body.scrollLeft;
y1=y+document.body.scrollTop;
rectangleHide("area");
inputUpdate();
}
else
{
x2=x+document.body.scrollLeft;
y2=y+document.body.scrollTop;
pointCorrect();
inputUpdate();
}
ptype = !ptype;
}
//correcting TL BR coordinates if they are switched
function pointCorrect(x1c,y1c,x2c,y2c)
{
.
}
//rectangle drawing (x1,y1); (x2,y2)
function rectangleDraw(rectId)
{
.
}
// rectangle drawing from input fields
function rectangleDrawInput(rectId)
{
.
}
//rectangle hiding
function rectangleHide(rectId)
{
.
}
//input fields update functions
function inputUpdate()
{
.
}
function inputWidthUpdate()
{
.
};
function inputHeightUpdate()
{
.
};
function inputXYUpdate()
{
.
};
//prepare for thumbnail generation
function generateImageThumb()
{
var previewclass="preview";
var previewimage="/preview.gif";
var links=document.getElementsByTagName("a");
var prevlinks=new Array();
var c=0;
var previewTest = new RegExp("(^|\s)" + previewclass + "(\s|$)");
for(I=0; I
7.2. Описание функций модуля thumbcreate.php.
//working area
//input-output form
8 Пример работы скрипта
Вы можете посмотреть пример в действии на этом сайте или перейти на сайт автора.
9 Ссылки
- Image previews with DOM JavaScript — http://icant.co.uk/articles/imagepreview/
- Сложное масштабирование изображений в PHP — http://codenet.ru/webmast/php/Image-Resize-GD/
10 ?сходный код
Advanced Thumbnail Creator: atc.zip
Библиотека thumbcreate.js: thumbcreate.js
Модуль thumbcreate.php: thumbcreate.php
Описание в формате PDF: atc.pdf
Жупаненко Андрей, оригинал сатьи: http://research.zhupanenko.com/atc/.
Добавлю:
rect.style.left=coords[0]+'px';
rect.style.top=coords[1]+'px';
rect.style.width=coords[2]-coords[0]+'px';
rect.style.height=coords[3]-coords[1]+'px';
следует указывать единицы измерения, если они отличны от ‘0′, в данном случае – ‘px’. Если их нет, то при указании DOCTYPE Firefox не отображает область выделения.
2007-03-10 at 1:33 pm
Между прочим, такого решения с JS-выделением я не встречал! Обязательно возьму на вооружение. Но вот PHP скрипт нуждается в правильном написании :)
2007-03-10 at 2:55 pm
Не совсем понятно почему обязательно делать изображения 70Х70. Логичнее масштабировать до размера максимальной стороны в 70px.
Совсем упущенны консольные утилиты, для масштабирования.
ЗЫ: РНР-скрипт дествительно совсем “детский”.
2007-03-10 at 8:19 pm
неудобно, глючно и плохо подходит, когда требуется изображение определённого размера.
если есть желание – можете попытаться распотрошить сей примерчик: http://katit.ru/imageditor/389c97b8d807154bea707ee5d149e89b.jpg/
2007-03-10 at 9:20 pm
[...] » Advanced Thumbnail Creator – hotibo.ru Работая с новостными лентами или же просто с информацией, содержащей графические изображения, довольно часто возникает потребность генер (tags: thumbnail php webdev javascript) [...]
2007-03-11 at 2:18 am
как по мне прикольно. уже использую в своей админке. спасибо
2007-03-12 at 1:53 pm
немного неудобно что два раза кликать надо, а так нормуль.
2007-03-12 at 9:17 pm
Напало на выходных вдохновение вот и переделал скрипт который делает миниатюры по средствам ручного выделения.
скачать можно тут http://welder.host-expert.com/scripts_docs/files/welder_thumbnail_creator.tar.gz
online тут http://welder.host-expert.com/demo/rezak/index.php
документация тут http://welder.host-expert.com/demo/rezak/readme.html
2007-03-25 at 12:01 am
2 welder
Большое спасибо за доработанный скрипт и открытые коды скрипта
PS: отдельное спасибо за документацию по установке, обычно леняться написать
2007-03-30 at 1:20 am
Вторая версия скрипта появмлась куча новых возможностей.
смотреть тут http://welder.host-expert.com/demo/thumb2/
скачивать тут http://welder.host-expert.com/hlam/thumb2.zip
2007-04-02 at 9:08 am
В яваскрипте следует учитывать прокрутку страницы, так как при скролле выделение происходит не там где кликает мышь.
Юзай
if(obj == window) {
var myWidth = 0, myHeight = 0;
if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
var scrOfX = 0, scrOfY = 0;
if( typeof( window.pageYOffset ) == 'number' ) {
//Netscape compliant
scrOfY = window.pageYOffset;
scrOfX = window.pageXOffset;
} else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
//DOM compliant
scrOfY = document.body.scrollTop;
scrOfX = document.body.scrollLeft;
} else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
//IE6 standards compliant mode
scrOfY = document.documentElement.scrollTop;
scrOfX = document.documentElement.scrollLeft;
}
return [scrOfX, scrOfY, myWidth,myHeight];
}
else if (obj == document.body) {
if (window.innerHeight && window.scrollMaxY) {
yScroll = window.innerHeight + window.scrollMaxY;
xScroll = window.innerWidth + window.scrollMaxX;
} else if (obj.scrollHeight > obj.offsetHeight){ // all but Explorer Mac
yScroll = obj.scrollHeight;
xScroll = obj.scrollWidth;
} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
yScroll = obj.offsetHeight;
xScroll = obj.offsetWidth;
}
return [xScroll, yScroll];
}
else {
if (obj.offsetParent) {
curleft = obj.offsetLeft
curtop = obj.offsetTop
var objParent = obj;
objParent = objParent.offsetParent;
while (objParent) {
curleft += objParent.offsetLeft
curtop += objParent.offsetTop
objParent = objParent.offsetParent;
}
}
return [curleft, curtop,obj.offsetWidth,obj.offsetHeight];
}
}
тоесть координата выделения будет следующая
document.getElementById("имя_слоя").style.left=getDim(window)[0]+e.clientX+"px";
document.getElementById("имя_слоя").style.top=getDim(window)[1]+e.clientY+"px";
Данный код является совместимым с IE,FireFox,Opera. ? отвечает стандартам XHTML 1.0 Strict
2007-04-16 at 7:44 pm
?звините, но разговор вообще ни о чем – юзабилити ноль во всех предложенных здесь вариантах, кроме варианта dark-demon’а.
Постараюсь в скором времени оформить для выкладывания свой скрипт и поделюсь. Единственный открытый вариант уже довольно устарел, но все равно, на мой взгляд, гораздо полезнее.
2007-04-16 at 10:03 pm
Спасибо за оригинальное решение поставленной задачи.
2007-05-03 at 11:59 am
Спасиб :)
2007-05-04 at 2:35 pm
Надо же, даже не подумал бы что такое бывает :) Спасибо!
2007-05-17 at 5:12 pm
[...] 8. Набор функций, позволяющих получить координаты элемента на экране пользователя. Если ваш документ статичен относительно окна и не имеет скроллбаров – лучше использовать функцию getPosition – так будет быстрее. В обратном случае используйте getAlignedPosition – она учитывает положения скроллбаров. Только обратите внимание: значение top у элемента может быть орицательным, если элемент верхней частью за пределами окна – для синхронизации с курсором мыши иногда нужно обнулить в этом случае высоту. Основной скрипт позаимствован из одного блога, Aligned-версия – результат поисков по сусекам и совмещения с информацией из двух статей (при обнаружении DOCTYPE IE входит в свой собственный, несколько непредсказуемый, режим). [...]
2007-08-12 at 6:01 pm
Скажите, а есть ли какая то информация о том, по какому принципу сжимает картинки движок dle? Не очень нравится результат его работы – почему то сильно “замыливаются” картинки. http://skuterist.ru/uploads/posts/1197489721_01.jpg
Обратите внимание на цифры (дату фотографии). На оригинале они четкие, здесь – как будто смазаны.
Можно ли как то переписыть модель ужимки фотографии в дле?
2007-12-14 at 3:13 pm
+1, схожие мысли…
2008-05-20 at 3:15 pm
2 Welder,
сайт по указанному адресу не существует :(
А взглянуть на творчество ой как шибко хочется.
2008-06-02 at 2:39 am
К сожаление, вторая версия скрипта не доступна. Возможно автор обновит…
2008-07-29 at 12:59 am