В этом уроке я расскажу, как сделать возможным сохранение ролика или его части (мувиклипа) на диск в формате рисунка (jpg). Данный урок является продолжением серии уроков по созданию графического редактора (рисование линий), но может использоваться и в совершенно других целях.
1. Для начала работы нам потребуется дополнительный класс JPGEncoder, который находится в дополнительной библиотеке Adobe Core Library. Скачать его можно
на этой странице. Разархивируйте архив и найдите папку com (\as3corelib-.92.1\src\com) Ее нужно скопировать в каталог, где хранится Ваш *.fla файл.
2. В самое начало нашего кода помещаем строчку:
import com.adobe.images.JPGEncoder;
тем самым мы импортировали в наш скрипт класс JPGEncoder, который нужен нам для преобразования векторного изображения в растровое.
3. Поместим в нашу флешку кнопку и присвоем ей имя 'saveBtn':
После чего присвоим ей событие 'saveImage' (добавим в код вот эту строчку):
saveBtn.
addEventListener (MouseEvent.
CLICK, saveImage
);
4. Напишем функцию saveImage, которая и будет в последствии сохранять наш рисунок
Добавим в эту функцию такой код:
jpgSource.draw(this);
var jpgEncoder:JPGEncoder = new JPGEncoder(95);
var jpgStream
:ByteArray = jpgEncoder.encode
(jpgSource
);
Первая строчка создает объект BitmapData с шириной в 550 и высотой в 400 пикселей. Вторая строчка прорисовывает весь флеш ролик в этом объекте (впоследствии мы модифицируем код и сделаем так, чтобы сохранялся только рисунок)
Третья строчка кодирует полученное изображение в формате jpg в качестве 95%, для изменения качества нужно вписать вместо 95 другое значение...
Четвертая строчка сохраняет изображение как последовательность битов, чтобы передать ее в пхп скрипт, который и займется сохранением файла.
5. Создание пхп скрипта для сохранения.
Ниже представлен пхп код, который будет сохранять эот файл на локальный компьютер. Пхп - программисту не составит сложности модифицировать его таким образом, чтобы, например, сохранять его на сервере, или производить с ним какие - либо действия. Сам код, как и основные моменты данного урока я подсмотрел
тут. Итак,
<? if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
// get bytearray
$jpg = $GLOBALS["HTTP_RAW_POST_DATA"];
// add headers for download dialog-box
header('Content-Type: image/jpeg');
header("Content-Disposition: attachment; filename=".$_GET['name']);
}
?>
Этот пхп файл необходимо сохранить на веб (или локальном сервере) для его выполнения.
!Важно! При сохранении пхп файла в кодировке utf8, данный пример может не сработать по некоторым причинам, поэтому рекомендую сохранять его в западноевропейской кодировке. 6. Передача в пхп картинки из flash
Добавим в нашу функцию 'saveImage' следующий код:
var jpgURLRequest
:URLRequest =
new URLRequest('http://ecomodul.com.ua/flash_tests/saveImage.php?name=actscript.jpg');
jpgURLRequest.requestHeaders.push(header);
jpgURLRequest.data = jpgStream;
navigateToURL(jpgURLRequest, "_self");
в итоге наша функция 'saveImage' будет иметь следующий вид :
jpgSource.draw(this);
var jpgEncoder:JPGEncoder = new JPGEncoder(95);
var jpgStream
:ByteArray = jpgEncoder.encode
(jpgSource
);
var jpgURLRequest
:URLRequest =
new URLRequest('http://ecomodul.com.ua/flash_tests/saveImage.php?name=actscript.jpg');
jpgURLRequest.requestHeaders.push(header);
jpgURLRequest.data = jpgStream;
navigateToURL(jpgURLRequest, "_self");
}
Причем, вместо 'http://ecomodul.com.ua/flash_tests/saveImage.php' следует вписать адрес пхп-скрипта, созданного в 5м пункте, а вместо 'actscript.jpg' нужно вписать любое другое название, под которым Вы хотите сохранить картинку.
7.
Вот пример того, как это должно выглядетьЕсли что-то не получилось, то как всегда
можно взять уже готовенькое. Но эта флешка сохраняет не только наш рисунок, но и всю себя, поэтому нужно модифицировать наш код...
9. Нарисуем во flash(е) белый прямоугольник с черной границей (цвета могут быть другими), сохраним его как мувиклип и присвоим имя 'drawSurface'. Это и будет наше "полотно" для рисования:
10. Создайте пустой мувиклип и поместите его в 'drawSurface' с координатами (0;0). Назовите его 'drawing':
11. Создайте слой-маску, которая будет маскировать 'root.drawSurface.drawing'. Причем маска должна полностью совпадать по координатам с белой подложкой 'drawSurface'(а):
Эта маска нужна для того, чтобы линия, которая будет выходит за грани 'полотна' не отображалась.
12. Теперь модифицируем код. Для начала сделаем так, чтобы линия рисовалась не непосредственно в ролик, а в мувиклип 'drawSurface':
Найдем в коде следующие строки:
this.graphics.lineStyle(this.sizeSlider.value, this.cp.selectedColor, this.opacitySlider.value); //Линия имеет ширину, прозрачность и цвет, равную положениям компонентов
this.graphics.moveTo( mouseX, mouseY);////Ставим "начало" линии в точку положения курсора
drawing = true;//Начинаем рисовать
}
И изменим их на:
this.drawSurface.drawing.graphics.lineStyle(this.sizeSlider.value, this.cp.selectedColor, this.opacitySlider.value); //Линия имеет ширину, прозрачность и цвет, равную положениям компонентов
this.drawSurface.drawing.graphics.moveTo(drawSurface.mouseX,drawSurface.mouseY);//Ставим "начало" линии в точку положения курсора
drawing = true;//Начинаем рисовать
}
Теперь изменим:
if(drawing){//Проверка переменной drawing
this.graphics.lineTo(mouseX,mouseY);//Линия ведется к новой координате
}
}
на
if(drawing){//Проверка переменной drawing
this.drawSurface.drawing.graphics.lineTo(this.drawSurface.mouseX, this.drawSurface.mouseY);//Линия ведется к новой координате
}
}
И последнее:
function changeLineStyle
(event
:Event) : void {
this.graphics.lineStyle(this.sizeSlider.value, this.cp.selectedColor, this.opacitySlider.value);//Линия меняет ширину, прозрачность и цвет, в зависимости от положения компонентов
}
На:
function changeLineStyle
(event
:Event) : void {
this.drawSurface.drawing.graphics.lineStyle(this.sizeSlider.value, this.cp.selectedColor, this.opacitySlider.value);//Линия меняет ширину, прозрачность и цвет, в зависимости от положения компонентов
}
13. Теперь наш листинг выглядит таким образом:
import com.adobe.images.JPGEncoder;
// Переменная drawing будет определять, рисовать ли линию в данный момент.
var drawing:Boolean = false;
// Присвоим ролику события
stage.addEventListener(MouseEvent.MOUSE_DOWN, startDrawing); //Если мышь нажата, начинает рисовать
stage.addEventListener(MouseEvent.MOUSE_MOVE, drawIt); // При движении мыши рисует линию
stage.addEventListener(MouseEvent.MOUSE_UP, stopDrawing); // Если мышь отпущена, прекращает рисовать
this.cp.addEventListener(Event.CHANGE, changeLineStyle);
this.sizeSlider.addEventListener(Event.CHANGE, changeLineStyle);
this.opacitySlider.addEventListener(Event.CHANGE, changeLineStyle);
saveBtn.addEventListener (MouseEvent.CLICK, saveImage);
function startDrawing(event:MouseEvent):void{
this.drawSurface.drawing.graphics.lineStyle(this.sizeSlider.value, this.cp.selectedColor, this.opacitySlider.value); //Линия имеет ширину, прозрачность и цвет, равную положениям компонентов
this.drawSurface.drawing.graphics.moveTo( this.drawSurface.mouseX, this.drawSurface.mouseY);//Ставим "начало" линии в точку положения курсора
drawing = true;//Начинаем рисовать
}
function drawIt (event:MouseEvent){
if(drawing){//Проверка переменной drawing
this.drawSurface.drawing.graphics.lineTo(this.drawSurface.mouseX,this.drawSurface.mouseY);//Линия ведется к новой координате
}
}
function stopDrawing (event:MouseEvent) :void {
drawing = false;//Прекращаем рисовать
}
function changeLineStyle (event:Event) : void {
this.drawSurface.drawing.graphics.lineStyle(this.sizeSlider.value, this.cp.selectedColor, this.opacitySlider.value);//Линия меняет ширину, прозрачность и цвет, в зависимости от положения компонентов
}
function saveImage (event:MouseEvent) : void {
var jpgSource:BitmapData = new BitmapData (550, 400);
jpgSource.draw(this);
var jpgEncoder:JPGEncoder = new JPGEncoder(95);
var jpgStream:ByteArray = jpgEncoder.encode(jpgSource);
var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
var jpgURLRequest:URLRequest = new URLRequest('http://ecomodul.com.ua/flash_tests/saveImage.php?name=actscript.jpg');
jpgURLRequest.requestHeaders.push(header);
jpgURLRequest.method = URLRequestMethod.POST;
jpgURLRequest.data = jpgStream;
navigateToURL(jpgURLRequest, "_self");
}
14. Если вы запустите получившийся ролик, то увидите, что рисование происходит только на "полотне" и не выходит за его пределы. Остается последнее: сделать так, чтобы при нажатии кнопки "сохранить" флеш сохранял только наш рисунок, для этого вместо:
jpgSource.draw(this);
напишем такую строчку:
jpgSource.draw(drawSurface);
в итоге при нажатии кнопки 'saveBtn' будет сохраняться уже наш рисунок. Осталось изменить его ширину и высоту:
Поменяем строчку:
var jpgSource:BitmapData = new BitmapData (550, 400);
на:
var jpgSource:BitmapData = new BitmapData (this.drawSurface.width, this.drawSurface.height);
Теперь можно проверить. Мой пример
тутА исходник
тут