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

   
Скачать флеш исходники уроки примеры flash игры с исходниками

Сохранение картинки на сервер из флешки (actionscript 2)

Флеш примеры и уроки
Продолжение статьи Изготовление флеш рисовалки как вконтакте граффити - сохранение картинки на сервер и далее на компьютер пользователя средствами actionscript 2.0, нужен сервер с поддержкой php.
Возможность получить байт код картинки (класс ByteArray) не доступен в actionscript 2, мы располагаем только функцией считывания цвета конкретного пиксела:
getPixel(x,y); , где х и у - координаты нужного пиксела.
Конечно, самый простой способ сохранить изображение из флешки на сервер - брать цвета каждого пикселя на холсте для рисования, формировать из этого двумерный массив и отсылать на php скрипт, который сделает из этого всего jpg или png картинку. Но, начав реализовывать этот способ, вы столкнётесь с некоторыми проблемами. Например, флеш ограничивает время выполнения циклов, если цикл не успел выполниться за 10 секунд (т.е. большая вероятность, что он просто уходит в бесконечность), flash плеер покажет вам окно с предупреждением, и этот цикл прервётся. Всё это к тому, что для того, чтобы за 10 секунд прочитать каждый пиксель холста 400 на 500 пикселов вам нужна будет мощная машина, у остальных же пользователей никак не получится сохранить картинку smile И даже если вы извратитесь и сделаете это всё не в одном, а нескольких циклах, пользователю прийдётся передать на сервер ровно 6*400*500 байт (1,2 мегабайта для холста 400 * 500 пикселов), что существенно увеличит время сохранения картинки.
К счастью для нас, многоуважаемый quasimondo реализовал отличный способ сохранить картинку из flash плера на сервер. Заключается он в том, что холст для рисования постепенно сканируется и кодируется в base 64, причём пока первая часть отправляется на сервер, подготавливается следующай часть, кодирование в base 64 существенно экомномит исходящий траффик, конечно, время сохранения картинки на сервер.
Оригиналы всех использованых мной классов и скриптов находятся здесь http://www.quasimondo.com/archives/000645.php, рекомендую ознакомиться.
Итак, наша задача - добавить в нашу рисовалку функцию сохранения картинки (например, png) на сервер.
Для начала вам нужно сделать эту самую рисовалку, либо скачать исходник. Далее нужно добавить в неё кнопку, при нажатии на которую нарисованое вами изображение сохранится на сервере. Назовём её save_btn (как в примере), и, чтобы не выбиваться из стиля, пропишем для неё useHandCursor:
save_btn.useHandCursor = false;

Для того, чтобы во время сохранения пользователь не мог ничего дорисовывать и нажимать какие-либо кнопочки, сделаем ещё один слой, выше всех, нарисуем прямоугольник чёрного цвета, такими размерами, при которых он бы закрывал всю флешку, конвертируем его в MovieClip, называем, например, Блок. Заходим "в него", конвертируем квадрат в MovieClip, делаем ему alpha несколько процентов (чтобы был немного сероватый), даём instance name b. На кадр вешаем:
b.onPress = b.onPress; // небольшая хитрость.
// Сделано для того, чтобы наш клип "перехватывал" на себя все клики по флешке
b.useHandCursor = false;// это для того, чтобы курсор не сменялся на "руку" и всё выглядело вполне реалистично

Также рекомендую поверх слоя с этим прямоугольником сделать ещё один слой, на котором сделать надпись, что-то типа "отправка изображения на сервер", либо же воспользоваться этим замечательным сервисом для генерации красивых gif анимаций, позволяющих пользователю не скучать при отсылке на сервер wink
Теперь после всего старого кода добавляем новый (для кода механизма сохранения картинки на сервер я сделал отдельный слой) и пишем туда вот что (исходные комментарии сохранены, кое-где добавлены новые для удобства, плюс сам механизм немного переделан):
import flash.display.BitmapData; // импортируем класс, необходимый для снятие снимков клипов
import com.quasimondo.display.BitmapExporter; // импортируем класс BitmapExporter
bl._visible = false; // скрываем блок
var dir = 'BitmapExporter_Tempfiles/'; // название папки, куда должны сохраняться картинки

var type = '.png'; // тип файла - можно задать jpg, png или даже bmp  :smile:

var snapshot:BitmapData = new BitmapData(580,345,false);

BitmapExporter.gatewayURL = "BitmapExporter.php"; // путь к скрипту

BitmapExporter.blocksize = 100000;

// It is a good idea to listen to the various events that
// BitmapExporter provides:
BitmapExporter.addEventListener( "progress", this);
BitmapExporter.addEventListener( "status", this);    
BitmapExporter.addEventListener( "error", this);
BitmapExporter.addEventListener( "complete", this);


save_btn.onRelease = function() {
bl._visible = true; // показываем блок
    // Check if there is still an export going on:
    if (BitmapExporter.getStatus() == "idle") {
        
        // update the bitmap with the latest camera image:
        snapshot.draw(pole);
        
        progress_back._visible = progressbar._visible=true;
        
        // this is only to compare the different speeds
        timer = getTimer();
        onEnterFrame = updateTimer;
        
        BitmapExporter.saveBitmap(snapshot, "snapshot"+type, "turboscan", 0, 70 );

        // Usually it is recommended to use one of the other modes:
        // BitmapExporter.saveBitmap(snapshot, "snapshot.jpg", "fastscan", 0,  70);
        // BitmapExporter.saveBitmap(snapshot, "snapshot.jpg", "default", 0,  70);
        // BitmapExporter.saveBitmap(snapshot, "snapshot.jpg", "palette", 0,  70);        
        // BitmapExporter.saveBitmap(snapshot, "snapshot.jpg", "rgb_rle", 0,  70);
        
    }
}

function updateTimer(){
    time.text = getTimer() - timer;
}


function progress(evt:Object):Void {
    progressbar.setProgress(evt.current, evt.total);
    progressbar.label = evt.message+" (%3%%)";
}

function error(evt:Object):Void { // ошибка
    delete onEnterFrame;
    bl._visible = false; // скрываем блок
}

function status(evt:Object):Void {

    
    switch (evt.status) {

        
    case "idle" : // когда картинки сохранена

        onEnterFrame = null;
        getURL(dir+uniqueID+type, '_blank'); // открываем сохранённую картинку в новом окне
        bl._visible = false; // скрываем блок
        break;
        
    case "retrieving":
        onEnterFrame = null;
        break;
    }
}

Как видите, код немного отличается от оригинала, но по-моему, он стал даже немного удобней и короче. В моём примере после сохранения картинки она просто открывается в новом окне. Если вас это устраивает - замените
getURL(dir+uniqueID+type, '_blank');

На нужные вам действия, как вариант, отправляйте пользователя на какой-либо скрипт и передавайте ему ссылку на картинку этого пользователя. Как вы видите, путь к картинке на сервере формируется из трёх переменных:
dir - папка с картинками;
uniqueID - уникальное имя файла, которое генерируется скриптом;
type - расширение файла (jpg, png или bmp).
Важно! Не забудьте создать папку, в которую будут сохраняться ваши картинки, в наем примере она будет называться BitmapExporter_Tempfiles, на неё нужно установить права, достаточные для записи в неё php скриптами (на большинстве хостов нужны права 777).
Php скрипт и сам класс я тоже немного переделал, но приводить здесь не буду, вы можете скачать их вместе с примером и исходником. Опции сохранения картинки:
1) Можно выбрать тип файла, поддерживается компрессия в jpg, png и даже bmp smile Тип можно менять в переменной type.
2) Выбор алгоритма и степени компрессии, передаются при вызове метода BitmapExporter.saveBitmap
BitmapExporter.saveBitmap(snapshot, "snapshot"+type, "turboscan", 70 );

Здесь:
snapshot - ссылка на клип, который нужно сохранить на сервере;
"snapshot"+type - в принципе можно ставить что угодно, главное, чтобы с нужным расширением.
"turboscan" - алгоритм компрессии.
Последний параметр - степень компрессии (имеет значение только для типа .jpg).
Поодерживаемые алгоритмы компрессии:
turboscan - конвертирование в base10, быстрое сканирование, но обьём передаваемых данных больше;
fastscan - конвертирование в base36, сканирование проходт медленнее, но обьёи данных выходит меньше;
default - конвертирование в base128;
rgb_rle - длина каждого цвета кодируется отдельно
palette - конвертирование в base128, создание палитры. Долгое кодирование, минимальный обьём исходящих данных.
В общем, можете собирать всё сами, либо же скачать мой пример сохранения картинки на сервер с исходником. Показывать на своём хостинге не хочу, потому что файлы, как вы понимаете, пока не удаляются smile засерать диск неохота. Позже доработаю, чтобы показать можно было в действии. Можете тестировать на своём сервере (не забудьте выставить нужные права), либо ставьте Денвер и запускайте у себя на машине fellow
Скачать рабочий пример с исходником

 (голосов: 11)

Почитать ещё:
 
#1 написал: Влад (1 мая 2009 15:09)
уже качаю.
admin, подправьте шаблон, т.к. особой пользы от кнопок "Поддержка" и "Регистрация" нет, болтаются бестолку
#2 написал: Влад (1 мая 2009 23:47)
это мне кажется, или файл с исходником не тот? изменений не увидел, да и скриптов нет внутри. я уже наверное задолбал с комментами? :)
#3 написал: admin (4 мая 2009 15:18)
Нет, вам не кажется, я не ту ссылку вставил recourse
Поправил, извините.

Насчёт шаблона, тоже собираюсь давно до ума довести, но, как всегда руки не доходят smile
#4 написал: САня (14 мая 2009 01:23)
А сколько трафика расходуется на передачу холста 400 500 при таком методе.

Что то мне кажется что не мало.

Может есть вариант на стороне юзера создать картинку и отправить уже готовый png
#5 написал: admin (14 мая 2009 01:32)
Смотря какая картинка, конечно, но во всяком случае не больше сотни килобайт.
Может есть вариант на стороне юзера создать картинку и отправить уже готовый png

Не встречал такого, может сам как-нибудь напишу, но пока что я не знаком с алгоритмами jpg и png компрессии. А вообще, по большому счёту, эта тема стала неактуальна с приходом Actionscript 3.
#6 написал: Влад (31 мая 2009 17:10)
для уменьшения выход. картинки нужно уменьшить параметры области в слое сохранения, размеры поля рисования, маски. Что еще? а то размер png тот что мне нужен, а сама картинка растянута. что я забыл?
#7 написал: admin (31 мая 2009 17:17)
Не совсем понял вопроса, но постраюсь помочь smile
Во-первых, не забыли ли вы изменить размер в этой строчке?
var snapshot:BitmapData = new BitmapData(580,345,false);

И ещё один вариант, как вы меняли размеры поля для рисования? Нельзя просто растягивать/сжимать мувик pole. Нужно зайти "внутрь" него и менять размеры белого квадрата.
#8 написал: Влад (31 мая 2009 21:31)
да, что-то плохо обьяснил :) спасибо, все стало как надо.
зашел "внутрь него" winked
#9 написал: Алена (8 июня 2009 18:20)
Здравствуйте, не скачивается? Написано, что файл нот фаунд :(
Не могли бы вы перезалить
Спасибо заранее
#10 написал: admin (16 июля 2009 13:47)
Да, конечно можно.
Но тогда во флешке эти переменные не нужно инициализировать, и, тем более, переопределять =)
Допустим, нужно передать тип картинки, переменную type
При вставке флешки на страницу передавайте переменную через GET:
ris.swf?type=.jpg

И во флешке нужно будет убрать строку
var type = '.png';
#11 написал: life.music (21 июля 2009 15:16)
admin,

Чёто не работает сохранение...Вообще флеш не показывает, пишет: "
К сожалению, у Вас не установлен flash плеер." хотя флеш плеер стоит. А если включать флешку без swfobject тоесть тегами object и embed то флешка есть, но не сохраняет.. пробывал и на локалхосте и на совершенно другом хостинге. В чём проблема не подскажешь?
#12 написал: life.music (21 июля 2009 15:49)
admin,
Оказывается там у меня ошибка в путе к sfwobjectУ была..незаметил чёто, но всёравно не сохраняется. На локалхосте выводиться ссылка в новом окне с цыфрами...например "http://localhost/BitmapExporter_Tempfiles/8cfac390020bfeb2653bce2f1480ce
3a.png", а на хостинге сцылка уже с "undefined.png"...не понимаю О_о
#13 написал: admin (21 июля 2009 15:55)
Попробуйте сменить тип на jpg, так как сохранение в png более ресурсоёмко
#14 написал: life.music (22 июля 2009 11:06)
admin,
не работает всёравно. А нужны какие либо настройки сервера?
#15 написал: admin (22 июля 2009 11:44)
Нет, не нужны. Ваш хостинг точно поддерживает php скрипты? Проверьте права на папку, в которую должны сохраняться картинки (должны быть достаточные для записи в неё), и права на сам скрипт (права, достаточные для запуска)
#16 написал: life.music (22 июля 2009 15:33)
admin,
Да конечно подерживает php. И права на все файлы 777. А Вы проверяли у себя на машине? Всё работает?
#17 написал: admin (23 июля 2009 12:00)
Да, всё работает
#18 написал: Sheva (2 августа 2009 12:37)
Классная рисовалка!!! А подскажите как сделать добавление на поле что-то вроде клипарта с возможностью перемещения и включения его в сохраняемый файл (а если еще и размеры можно было бы изменять...) Примерно как на Яндексе. Спасибо.
#19 написал: admin (2 августа 2009 14:01)
Хм... ну, это в двух словах не обьяснишь)
#20 написал: Sheva (2 августа 2009 17:48)
Ну может не в двух... Неужели это так сложно??? Ну что ж, буду искать (
#21 написал: pokemon (2 августа 2009 20:26)
респееееееект автору!!!!! спасибо!!! lol

а хотя нет, таже фигня
The requested URL /ris/1/BitmapExporter_Tempfiles/bc6cf05cf0c3faf139ccfe921e73a683.png was not found on this server.
#22 написал: admin (2 августа 2009 23:36)
Проверьте пути в папкам и скриптам и проверьте права на них
#23 написал: Antoshka (5 декабря 2009 20:39)
Привет!
Скрипт отличный, даже поставил себе Adobe Flash CS4 и начал его изучать. Респект за все :)
Удалось изменить кнопки, переместить их в другое место, задать им свои actions, но вот возникли проблемы:
1) при экспорте всего этого во флешку .swf палитра становится мутной, т.е. один цвет уже не однотонный, а многотонный, где каждый пиксель того же цвета, но немного другого оттенка. Как от этого избавится? Если не исправить это дело, то поскольку цвет берется из пикселя, то будем иметь разные цвета из одной ячейки.
2) решил заменить ajax-loader.gif. Сделал новый, импортировал, удалил старые bitmap, но вот теперь новый ajax-loader.gif не отображается, появляется только слой "блок". Его надо как-то связать со слоем? Как это сделать? Или что надо вообще сделать? Новые битмапы создались.
3) почему внутри так много лишних элементов, например, видел там "ластик", кажется. Еще стрелку четырехсторонную. Все удалил, чтобы объем уменьшился, это предполагалось, что будут эти элементы?
4) как-то можно сделать, чтобы ячейка в палитре, из которой выбран цвет обводилась, скажем в белый квадратик, чтобы было ясно какой цвет сейчас используется? Это случайно в следующей версии не планируется добавить? :)
Ну вот собственно и все основные вопросы. Надеюсь, получить ответы с учетом, что я только сегодня поставил Adobe Flash CS4, и с учетом, что именно Adobe Flash. Одним словом, терминологии вашей пока не понимаю, других программ не использую :)
Еще хочу заметить, что все те, у кого проблемы с тем, что пишет будто бы не установлен плагин flash, то все дело в путях - надо чтобы скрипт лежат в корне, либо исправить пути.
#24 написал: alex (29 декабря 2009 22:05)
Здраствуйте! Просто супер пупер скриптик! спасибо!!

Как включить большую палитру?
#25 написал: Antoshka (4 января 2010 00:41)
Со своими вопросами в 23-ем посте разобрался сам. Правда было не легко.
Палитру заменил на свою с другим набором цветов и исчезли все глюки.
А прелоадер, разбитый на битматы, сварганил по новой по временным интервалам.
Насчет обводки ячейки с цветом пока не задумывался, но потом может доберусь и до этого :)
Спасибо за скрипт и с наступившим новым годом всех! :)

alex (пост 24), а разве эта палитра там как-то включается, в исходниках сама палитра подразумевается, причем там много чего есть из того, что не выведено на "холст" флешки. Я вот просто заменил палитру на свою, и ты можешь сделать так - будет тебе большая палитра :)
#26 написал: kirill1927 (9 января 2010 10:29)
404
/photo/BitmapExporter_Tempfiles/396f3be93cbe496404d6f1e1eeea6081.png

дай свою аську там обсудим и сюда выложим готовый вариант, или напиши сам 95653один[/right]
#27 написал: vantic (14 января 2010 15:03)
а что за ошибка?
Error opening URL 'http://188.93.17.145/risovalka/BitmapExporter.php'
[onAddPixelBlock] HTTP error 0
хотя темпы создает в папке,но картинок нет
#28 написал: Dimon (26 января 2010 14:03)
А как можно из TEMP фаила получить картинку?

У меня проблема в том что некоторые рисунки нормально сохраняются, а некоторые нет.. Просто temp фаилы.

А ещё очень долго сохраняет: и исходящий трафик составляет 2.5 метра. Не чего касающего сохранения не менял в исходнике!
#29 написал: hente (9 февраля 2010 14:57)
можно ли сохранить изображение с сохранением прозрачности и как это сделать????
За ранее благодарен:)
#30 написал: Андрей (25 марта 2010 21:02)
Классный исходник, единственная беда, долго сохраняет((
попробовал менять алгоритм компрессии при
turboscan: сохраняет качественно, но долго
fastscan: так же долго но не очень качественно
default:
rgb_rle: вообще не работает
palette: сохраняет быстро, но не качественно.

основной косяк, что при любом типе компрессии кроме турбоскан, вместо белого фон становится серым(
Добавление комментария




Опечатались, когда набирали запрос? Не беда! :)
фвщиу адфыр ehjrb bc[jlybrb фсешщтыскшзе akti флаш flesh crfxfnm
Мир технологии flash. Флеш уроки, исходники, примеры, статьи, советы, игры.