Продолжение статьи
Изготовление флеш рисовалки как вконтакте граффити - сохранение картинки на сервер и далее на компьютер пользователя средствами actionscript 2.0, нужен сервер с поддержкой php.
Возможность получить байт код картинки (класс ByteArray) не доступен в actionscript 2, мы располагаем только функцией считывания цвета конкретного пиксела:
getPixel(x,y); , где х и у - координаты нужного пиксела.
Конечно, самый простой способ сохранить изображение из флешки на сервер - брать цвета каждого пикселя на холсте для рисования, формировать из этого двумерный массив и отсылать на php скрипт, который сделает из этого всего jpg или png картинку. Но, начав реализовывать этот способ, вы столкнётесь с некоторыми проблемами. Например, флеш ограничивает время выполнения циклов, если цикл не успел выполниться за 10 секунд (т.е. большая вероятность, что он просто уходит в бесконечность), flash плеер покажет вам окно с предупреждением, и этот цикл прервётся. Всё это к тому, что для того, чтобы за 10 секунд прочитать каждый пиксель холста 400 на 500 пикселов вам нужна будет мощная машина, у остальных же пользователей никак не получится сохранить картинку

И даже если вы извратитесь и сделаете это всё не в одном, а нескольких циклах, пользователю прийдётся передать на сервер ровно 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 анимаций, позволяющих пользователю не скучать при отсылке на сервер
Теперь после всего старого кода добавляем новый (для кода механизма сохранения картинки на сервер я сделал отдельный слой) и пишем туда вот что (исходные комментарии сохранены, кое-где добавлены новые для удобства, плюс сам механизм немного переделан):
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

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

засерать диск неохота. Позже доработаю, чтобы показать можно было в действии. Можете тестировать на своём сервере (не забудьте выставить нужные права), либо ставьте Денвер и запускайте у себя на машине
Скачать рабочий пример с исходником