Вебмастеру

 
 
30

Сохранение изображения с помощью кнопки

  • Категория: html
У меня есть изображение, с помощью ява скрипт я его здорово изменил, теперь мне надо его сохранить на компьютере, т.е. пользователь загружает изображение с моего сайта, изменяет его, но его надо сохранить, при чем при помощи кнопки, где пользователь выбирает место где может сохранить данный рисунок, вопрос как это сделать?
 
 
1

Денис

  • группа: Гости
Чистый js не имеет доступа к файловой системе.
Для IE сохранение можно сделать с помощью ActiveX.

Вообще говоря другие варианты существуют, но скажите, как вы "изменяете" изображение с помощью js? Можно посмотреть пример?
 
 
2

Евгений

  • группа: Гости
присоединяюс, очень интересно!
 
 
3

Алексей

  • группа: Гости
Что сложного беру готовые библиотеки по изменинию изображения, например и оттуда беру функции по работе с изображениями, единственное, что сделал сам это написал увеличение и уменьшение. Ну для примера увеличение
function umen()
{
var d=document;
x=d['sq'];
if (!(x) && d.all) x=d.all['sq'];

if (x.height <=120){document.getElementById('st').innerHTML = '<p>Нельзя больше уменьшить фотографию</p>';
setTimeout(function(){document.getElementById('st').innerHTML = ''}, 2000);}
else {if ((x.height/2)<120){x.height=120}
else{
if ((x.height/2)>120){x.height=x.height/2}
}}
}
Тут самая главная тонкость, чтобы во всех брузерах все работало и выглядело все одинаково. Sq - id изображения, все элементы на странице лежат абсалютно, т.е абсалютное позиционирование, ну блин осталось только сохранить, а это не получается, пробую через Php он самне измененный рисунок сохраняет, т.е. если я изменил на яве рисунок, он это не воспринимает. Уже давно мучаюсь ничего придумать не могу. А надо уже давно все сделать
 
 
4

Алексей

  • группа: Гости
Я находил в инете коды, но они такие новороченные, что глючат все ужастно, ну короче у меня что ли кривые руки. Зайдешь в ините на какой-нибудь сайт работает все прекрасно там на сайте, т.е. измененные изображения в яве сохраняются там в демопримерах, устанавливаешь у себя скачиваешь работает как-то совершенно неправильно
 
 
5

Алексей

  • группа: Гости
Народ, если кто знает на чем угодно сохранять надо хоть ажаксе, хоть на флеше, хоть на PHP, только подкиньте идею и хоть немного объяните, а то вообще вилы, не могу ничего придумтать
 
 
6

Денис

  • группа: Гости
Могу подсказать только для случая, если используется htm5-тег canvas.
Из canvas можно получить изображение, закодированное в base64.
Дальше есть два пути:

1) Использовать data:uri.
Пользователь сможет либо посмотреть картинку в новой вкладке, либо сохранить под стандартным именем, но без расширения.
Описание способа, вместе с кодированием canvas в base64: http://http://www.nihilogic.dk/labs/canvas2image/

2) Отправить закодированное изображение на сервер (post).
Сервер преобразует его и вернет с необходимыми заголовками.
Пользователь увидит всплывшее окошко save as...

Сказать по правде, для реализации второго варианта пришлось поплясать с бубном. Думал окажется проще :)
Самые важные детали - заворачивание canvas в форму и небольшая обработка перед отправкой формы.
Рабочий пример (архив, html+php): http://http://dl.dropbox.com/u/7029820/sav...anvas-image.zip
 
 
7

Денис

  • группа: Гости
Честно говоря я слабо представляю, что кроме увеличения/уменьшения/перемещения можно написать подобным образом, просто изменяя размеры элементов.
Приведите, пожалуйста, пример сайта, на котором используется такой метод и сохраняются изображения.
 
 
8

Алексей

  • группа: Гости
МНе нужно сделать Он-лайн редактор фотографий, на чем угодно, это мой диплом, его через месяц уже сдавать,
что я сделал: через PHP загружаешь фотографию(изображение) при чем загружается только формата Jpg в папку из которой тут же удаляются остальные фотки.
Элементы на странице лежат абсолютно позиционировано.
Можно: растягивать фото по вертикали и горизонтали, увеличивать и уменьшать его, отражать фотографию,
делать черно-белой, поворачивать на 90%. Осталось только прописать сохораниение с этим уже месяц мучаюсь не получается!

Меняем задачу, из всего выше сказанного, чтобы мне надо изменить, чтобы написать этот редактор на флеше, кто этим делается
кто реально занимается этим,подскажите алгоритм. Блин из института могут выгнать, столько уже проучился жалко!!!
Пример для Дениса, размытие фотки
<div class="demo">

Сила размытия: <input type="text" id="value-amount" value="0" class="demo-input" style="width:30px;"/>

<input type="button" onclick="demo();" value="Размыть"/>
</div>
подключаем 2 библиотеки и все работает.
 
 
9

Byte

  • группа: Гости
Студенты млин пошли , взяли диплом и сделать не могут =))

Вообще предлагаю тебе все считать эффекты на стороне сервера и не париться.
 
 
10

Алексей

  • группа: Гости
каждый раз страница перегружается, это фигня получается
 
 
11

Денис

  • группа: Гости
Библиотека Pixastic?
Там изображение в конце концов превращается в canvas.
А я уже описал, как сохранить содержимое canvas'а.
 
 
12

Алексей

  • группа: Гости
Канвас - это в лисе и опере, в IE используются фильтры, он этот канвас не поддерживает , ладно сейчас скачал попробую разобраться в твоем примере. Спасибо
 
 
13

Денис

  • группа: Гости
Тоже верно. Ох уж этот недобраузер.
Единственное, что можно сделать с ним - подсказать пользователю, как нажать правую кнопку мыши :)
Да и то, вряд ли изображение сохранится с примененными фильтрами.

Остается только один вариант: рендеринг конечного результата на сервере.
 
 
14

Николай

  • группа: Гости
Люди, вы чего-то прикалуетесь...
Самый простой и кроссбраузерный вариант:
1. Любые состояния изменения картинки на клиенте должны быть синхронизированы на сервере с помощью AJAX.
2. При нажатии "Сохранить" мы выдаем СЕРВЕРНУЮ картинку, которая абсолютно идентична клиентской.
Для того, чтобы потоково отображалась картинка (т.е. браузер предлагал "открыть", "сохранить") надо добавить хедер "Content-Disposition"

З.Ы. Сам занимался подобным для коммерческого проекта: там мы делали именно подобным образом.
 
 
15

Денис

  • группа: Гости
Собственно под рендерингом результата на сервере я это и подразумевал.
Но с синхронизацией не при каждом изменении, а только перед сохранением.
 
 
16

Николай

  • группа: Гости
Только перед сохранением - вариант только в случае, если ты каждое изменение картинки с помощью яваскрипта где-то фиксируешь (хидден поля и т.п.). Если изменений будет много - будет непросто их все зафиксировать.
К тому же наверняка придется картинку изменять на сервере с помощью средств php или чего-либо подобного (ImageMagic к примеру).

З.Ы. Проблема времени конвертации решалась асинхронной обработкой изображений
 
 
17

Денис

  • группа: Гости
Если каждое изменение в отдельности - "атомарное", то можно просто вести историю изменений в виде стека.

Что-то изменили - толкнули параметры изменения в стек.
Отменили действие - вытолкнули из стека.
Хотим сохранить - js кодирует историю изменений в json например, записывает в одно hidden-поле и сабмитит форму. Сервер разбирает и последовательно повторяет изменения, потом отдает картинку.

Под "атомарными" изменениями я понимаю такие, которые можно свести к набору параметров (изменение размера, отражение, поворот, размытие всей картинки и т.д.). Они детерминированные - при одинаковом наборе параметров получается одинаковый результат.

Из "неатомарных" операций над изображением я могу придумать лишь... нет, ничего не могу придумать. Ничего, что было бы уместно сделать на js. Ничего, что возможно повторить в IE.

По поводу ImageMagic и иже. А чем это плохо? При постоянной синхронизации все равно ведь придется использовать :)
Да, при таком подходе на рендеринг результата будет уходить больше времени.
Да, возможно вместо распределенной по времени нагрузки мы получим импульсную.
Но зато сервер не будет дергаться по каждому чиху пользователя.
 
 
18

Николай

  • группа: Гости
Тю, да я ж не имел ввиду конвертацию на "каждом чихе".
Просто проще вести подобную историю - на сервере. Более того, это возможно даже удобней, если использовать некую модель данных.
ИМХО, лучше все настройки по максимуму хранить на серваке - больше секьюрности, меньше отображаемых хидден полей (по которым можно частично узнать "кухню") - т.е. меньше размер страницы, больше кроссброузерности. К тому же серваки сейчас такие, что лишние килобайты занятой рамы - просто ничто.
Если же на клиенте - дело хозяйское.
 
 
19

Денис

  • группа: Гости
Хорошо, с синхронизацией истории понятно. А когда, при таком подходе, сервер будет применять изменения к картинке?

Если один раз в конце - то я почти это и описываю. Но при постоянной синхронизации имеем N запросов, а при синхронизации перед сохранением - один.
Если при каждой синхронизации - будет много лишних обращений к файловой системе: прочитал, применил, записал, прочитал...
А ведь работа с ФС весьма медленная, в сравнении с другими операциями.

Если я правильно понял, то первый вариант? :)
 
 
20

Николай

  • группа: Гости
Фактическое изменение к картинке только один раз - при сохранении.

В общем смысл каков:
1. Изменяем картинку на клиенте с помощью js.
2. Историю изменения делаем на сервере с помощью аякса.
3. При сохранении конвертируем картинку (т.к. мы никак нормально не достанем измененное на клиенте изображение) дублируя функционал js с помощью ImageMagic к примеру.
4. Выдаем результат пользователю

Насчет "тонких" мест:
1. История храниться в оперативе
2. Конвертация происходит единожды
Они появились бы только в случае использования только серверной конвертации (без клиентской)
 
 
21

Денис

  • группа: Гости
Как так, в оперативе? Кажется, мы говорим о разных вещах :)

Php ведь не имеет прямого доступа к памяти. Единственный побочный эффект, который можно использовать для передачи состояния между разными запросами - сессии.

Я конечно теорезирую, но по моему это будет неэффективно :) Зачем гонять данные туда-сюда, если по факту они нужны только в конце?
Да и накладные расходы на кучу запросов выше, чем на один запрос с передачей полной истории изменений. Это конечно мелочи в наше время, но...
 
 
22

Николай

  • группа: Гости
Сам я ява разработчик. Но неужели ПХП все сессионные переменные хранит на стороне клиента? У нас у клиента в кукисах хранится только айди сессии, все остальное - в оперативе сервака.
Накладные расходы - фигня по сравнению с безопасностью и валидностью данных.

И последнее: мне по большому счету без разницы, где хранить историю. Можно еще раз внимательно прочитать мой пост #19
 
 
23

Денис

  • группа: Гости
Нет нет, конечно же на стороне сервера. Зря я вообще про это упомянул.
Что ж, дискуссия исчерпала себя.
 
 
24

Byte

  • группа: Гости
> каждый раз страница перегружается, это фигня получается
Ну это вы совсем деревня - можно тупо перегружать картинку. Тупо берем яваскрипт функцию которая спрашивает у сервер периодическии готова ли картинка , пока она не готова крутим индикатор загрузки - как только она готова меняем src у картинки =)
 
 
25

Алексей

  • группа: Гости
Все понятно - вот только можно было бы небольшой примерчик небольшой участок кода , который бы на примере показывал сохранение изображения, допустим что-то изменил в загружаемой картинки и тут же сохранил изменения в выбранную тобой папку.
Я может туплю, но у меня не получается вот я изменил картинку на клиенте с помощью js.
Как это дублировать с помощью Ajax изменения на картинке? как продублировать функционал js?
И как потом сохранить - буду очень благодарен?
 
 
26

Алексей

  • группа: Гости
Ну может кому поможет, просматривая участок кода что-то изменил для как казалось мне улучшения картинки, сохранил изменения, проверил на ferefox заработало все нормально, в опере же перестало что-то работать
Перестали работать некоторые елементы document.getElementById('st').style.position ="absolute" - восприниматься такие вот строчки, так как код просто огромный, теперь восстановить работоспособность редактора изображений видится невозможным(вот эти 4 дня мучался так и не сделал), так что теперь под лису надо сделать и и интернет эксплоуэр. Что еще интересно, так это, если ты работаешь непосредственно с id изображения(и др. эл. твоего приложения), то код какой бы он громоздкий для корректного изображения в firefox, нужно оставлять в именно в php файле, а не засовывать в jz, иначе в лисе почему-то работать начинает код с ошибками, ну это просто лирика. Но если несложно все-таки хочу найти ответы может я немного туплю, но не получается, все-таки новичок в этой сфере...

Как это дублировать с помощью Ajax изменения на картинке? как продублировать функционал js?
И как потом сохранить - буду очень благодарен?
 
 
27

Byte

  • группа: Гости
Вместо document.getElementById('st').style.position ="absolute" - попробуй использовать фреймворки.

А тестировать надо было изначально под ИЕ - меньше бы голова болела бы.

Вообще найди денег я тебе напишу прототип - который проапдейтишь и пропатчишь =)
 
 
28

Алексей

  • группа: Гости
Да блин тут надо под каждый браузер тестировать, смотря какая цена вопроса - в принципе можно договориться, напиши в личку что ты конкретно сделаешь и за какую конкретную сумму
 
 
29

Алексей

  • группа: Гости
Жду вашей помощи, смотрел по сайтам как-то не нашел ничего
 
 
30

Алексей

  • группа: Гости
Все на этом сайте разжевано, все работает, кроме сохранения фотографии, такой классный сайт получается, сейчас исправить все, там есть код, ну я что-то не могу его разобрать, какой-то он слишком мудренный, может кто поможет мне его использовать
ImageActions.Save = {

action : function(oImage, iX, iY, iWidth, iHeight, fncDone, oOptions)
{
var strData = oImage.toDataURL();

var oPost = new Net.HTTPRequest();

var fncImageSaved = function() {
var strID = oPost.getResponse();
//console.log(strID);
document.location.href = "./app/getimage/?id=" + strID + "&frm=" + oOptions.format;
fncDone(true);
}

oPost.listen("response", fncImageSaved);

strData = strData.substring(("data:image/png;base64").length+1);
//console.log("LEN:" + strData.length);
oPost.send(
"./app/saveimage/",
{
"data" : strData
}, "POST"
)

return true;
},

dialogname : "Save image",

dialog : function(oWindow, oSkin) {
var oCtr = oWindow.getContainer();

var oText = oCtr.addChildWidget(new GUI.Label(oSkin.Text));
oText.setText("You are about to download your image to your desktop. Please select a file format from the list below.");
oText.setAdjustToText(false);

var oFormatList = oCtr.addChildWidget(new GUI.SelectBox(oSkin.FormatList));
oFormatList.addItem("PNG", "PNG");
oFormatList.addItem("JPEG (Low quality)", "JPEGLOW");
oFormatList.addItem("JPEG (Medium quality)", "JPEGMEDIUM");
oFormatList.addItem("JPEG (High quality)", "JPEGHIGH");
oFormatList.addItem("BMP (Windows Bitmap)", "BMP");
oFormatList.addItem("WBMP (Monochrome)", "WBMP");

var oFormatLabel = oCtr.addChildWidget(new GUI.Label(oSkin.FormatLabel));
oFormatLabel.setText("Image format");

return function() {
return {
"format" : oFormatList.getValue()
}
}
},

menusetup : function(oSkin) {
return ["File", oSkin.File.Save, "Save"];
},

nonmaskable : false,

dataurl : true,

sourcefile : "actions/save.js"
 
 
Регистрация

Популярные статьи

» Mozilla Firefox: помощь и взаимоподдержка. Спрашиваем, ...
» Вопросы от новичков...
» перешли ли вы 100% на линукс без установленной параллел ...
» Ваши любимые плагины и дополнения
» Ответы на вопросы по PHP
» Какие CMS ВЫ предпочитаете - (плюсы и минусы)
» FAQ: вопросы и ответы
» Вопросы и консультации
» Другие браузеры (голосование!)
» Зарплата PHP программиста