injun #576871
injun

Главная > Сохраним флэш-графику как статичную картинку “at runtime”

 

 

Сохраним флэш-графику как статичную картинку “at runtime”

Сохраним флэш-графику как статичную картинку “at runtime”

Это перевод статьи Клайва Гудинсона, размещённой в Adobe DevNet и называющейся “Saving Flash graphics as image files at runtime”.

***

Если у вас появится желание моментально сконвертировать флэш-графику в статичную картинку, и сделать это средствами рантайма – например, для того, чтобы использовать на вашем сайте или дать возможность пользователю загрузить её и сохранить у себя на компьютере, то благодаря этому тутору вы узнаете как это делается: мы создадим кастомный AS3-класс Snapshot для этих целей.

Например, представьте, что вы разрабатываете программу-рисовалку, благодаря которой ваши посетители могут нарировать пару скетчей в реальном времени. Закончив рисовать вы можете поместить нарисованное в вашей галлереи в виде обычного jpeg-изображения.

И такой проект я реализовал – Pixton, который представляет созданные пользователями комиксы.

// один абзац вырезан цензурой за ненужностью.

Что понадобится?

Flash CS3 Professional

  • Попробовать
  • >Купить

Flash Player 9

Сервер, поддерживающий PHP 4 или выше

Пример использует простой PHP-скрипт, правда, если вы хотите, то вы можете перевести его на любую языковую платформу. 

Файлы с примерами:

  • snapshot_class_as3.zip (ZIP, 772K)

И прямые руки

Опыт работы с “server-side scripting” обязателен.

Поехали.

Изображение недоступно

Snapshot Explorer конвертирует графику в JPEG или PNG картинки. Попробуйте на реальном примере.

Напечатайте что-нибудь, выберите формат PNG и выберите опцию сохранения картинки.

Ну вот, теперь вы понимаете чем занимается Snapshot Explorer. А теперь посмотрим как он работает.

Качайте файлы с примерами.

Они содержат такие файлы:

  • snapshot.flp.
  • snapshot-example.fla, snapshot-example.swf, Main.as: эти файлы определяют пользовательский интерфейс Snapshot Explorer.
  • Snapshot.as: это – ActionScript-класс, с магией!

Ну ещё, вам понадобятся следующие публичные классы:

  • as3corelib: можно загрузить as3corelib из Google Code. Скопируйте папку src/com в classpath по вашему выборы. Вы также дожны добавить новый global classpath во Flash воспользовавшись Edit > Preferences > ActionScript > ActionScript 3.0 Settings. Классу Snapshot необходимы  com.adobe.images.PNGEncoder и com.adobe.images.JPGEncoder.
  • Base64: загрузить Base64 из Dynamic Flash и скопируйте класс в classpath по вашему выбору.

Пользовательский интерфейс

Во-первых, откройте snapshot-example.fla и Main.as. UI включает в себя следующее:

  • Textarea, которую вы можете подправить под себя.
  • Radio-кнопки, которые вы можете тоже изменить.
  • Кнопка “Capture”, которую вы тоже можете изменить.

Откройте панель “Actions” для Main.as. Скрипт начинается тем, что импортирует необходимые классы. В коде автоматом декларируется “Stage instances”, так что мы можем смело декларировать только две “RadioButtonGroup instances”:

package
{
   import com.goodinson.snapshot.*;
   import flash.display.*;
   import flash.events.*;
   import fl.controls.*;

   public class Main extends Sprite
   {
      private var grpAction:RadioButtonGroup;
      private var grpFormat:RadioButtonGroup;

// один абзац вырезан цензурой за ненужностью.

А вот код конструктора:

function Main()
{
   // скрываем UI пока инициализируемся
   visible = false;
   addEventListener(Event.ADDED_TO_STAGE, onReady);
}

В методе onReady() мы инициализируем наши radio-кнопки, потом устанавливаем действие при клике.

private function onReady(evt:Event):void
{
   // UI инициализировано
   visible = true;
   removeEventListener(Event.ADDED_TO_STAGE, onReady);

   // создаём группу radio-кнопок
   grpAction = new RadioButtonGroup("grpAction");
   grpFormat = new RadioButtonGroup("grpFormat");

   // и инициализируем её
   optJPG.group = grpFormat; optJPG.value = Snapshot.JPG;
   optPNG.group = grpFormat; optPNG.value = Snapshot.PNG;
   grpFormat.selection = optJPG;

   optDisplay.group = grpAction; optDisplay.value = Snapshot.DISPLAY;
   optPrompt.group = grpAction; optPrompt.value = Snapshot.PROMPT;
   optLoad.group = grpAction; optLoad.value = Snapshot.LOAD;
   grpAction.selection = optLoad;

   // указываем Snapshot URL
   Snapshot.gateway = "http://localhost/_e/snapshot/snapshot.php";

   btnCapture.addEventListener(MouseEvent.CLICK, onCapture);
}

А теперь переходим непосредственно к классу Snapshot. Для начала мы импортируем всё необходимое:

package com.goodinson.snapshot
{
   import com.goodinson.snapshot.*;
   import com.adobe.images.*;
   import com.dynamicflash.util.Base64;
   import flash.display.*;
   import flash.geom.*;
   import flash.net.*;
   import flash.events.*;
   import flash.utils.ByteArray;

После импорта, продеклариуем несколько констант:

public class Snapshot
{
   // указываем поддерживаемые типы изображений
   public static const JPG:String = "jpg";
   public static const PNG:String = "png";

   // указываем действия
   public static const DISPLAY:String = "display";
   public static const PROMPT:String = "prompt";
   public static const LOAD:String = "load";

   // параметры по умолчанию
   private static const JPG_QUALITY_DEFAULT:uint = 80;
   private static const PIXEL_BUFFER:uint = 1;
   private static const DEFAULT_FILE_NAME:String = ’snapshot’;

   // путь к серверным скриптам
   public static var gateway:String;

   public static function capture(target:DisplayObject, options:Object):void
   { 

А вот метод, который захватывает изображения:

public static function capture(target:DisplayObject, options:Object):void
{

Это первый шаг. Мы калькулируем координаты для захвата изображения:

var relative:DisplayObject = target.parent;
var rect:Rectangle = target.getBounds(relative);

Теперь определяем коррекцию транформации захвата цели:

var bitmapData:BitmapData = new BitmapData(rect.width + PIXEL_BUFFER * 2, rect.height + PIXEL_BUFFER * 2);
bitmapData.draw(relative, new Matrix(1, 0, 0, 1, -rect.x + PIXEL_BUFFER, -rect.y + PIXEL_BUFFER));

Следующим шагом станет калибровка – обратим BitmapData в ByteArray. Это фактические “слитие” двух массивов в один. И потом кодируется в один из выбранных пользователем форматов при помощи JPGEncoder или PNGEncoder.

// кодируем картинку
   var byteArray:ByteArray;
   switch (options.format)
   {
      case JPG:
      // если это JPG
      var jpgEncoder:JPGEncoder = new JPGEncoder(JPG_QUALITY_DEFAULT);
      byteArray = jpgEncoder.encode(bitmapData);
      break;

      case PNG:
      default:
      // если это PNG
      byteArray = PNGEncoder.encode(bitmapData);
      break;
   }

Заключительным шагом станет подготовка нашей картики для обработки на стороне сервера и обращения ByteArray в  String. Для этого используется класс Base64. Просто используется статичный метод encodeByteArray(), который возвращает наш ByteArray в качестве String, в дальнейшем которую мы отправим на сервер:

data
var byteArrayAsString:String = Base64.encodeByteArray(byteArray);

Теперь переходим к следующей части – обработке пользовательского запроса – сохранения картинки или записи её на стороне сервера.

var url:String = gateway + ‘?’ + Math.random();

// даём имя для файла при сохранении или показе картинки
var fileName:String = DEFAULT_FILE_NAME + ‘.’ + options.format;

// создаём URL request
var request:URLRequest = new URLRequest(url);

// отправляем данные через POST-метод
request.method = URLRequestMethod.POST;

var variables:URLVariables = new URLVariables();
variables.format = options.format;
variables.action = options.action;
variables.fileName = fileName;
variables.image = byteArrayAsString;
request.data = variables;

   if (options.action == LOAD)
   {
      options.loader.load(request);

   } else
   {
      navigateToURL(request, "_blank");
   }

Ну, а это простой php-скрипт:

<?php
switch ($_POST["format"])
{
   case ‘jpg’:
   header(‘Content-Type: image/jpeg’);
   break;

   case ‘png’:
   default:
   header(‘Content-Type: image/png’);
   break;
}

if ($_POST[‘action’] == ‘prompt’)
{
   header("Content-Disposition: attachment; filename=".$_POST[‘fileName’]);
}

echo base64_decode($_POST["image"]);
?>

Всё готово.

Спонсор поста: Интернет-магазин светильников для дома. Красивые хрустальные люстры, точечные светильники на заказ.

Похожие сообщения

 

Написано Сентябрь 30, 2008


Комментарии

— 01 Окт 2008 в 09:37 ∞ GB
Эх, где вы были года 2.5 назад?
Это баян :о)), для меня, по крайней мере.

— 01 Окт 2008 в 14:34 ∞ 576871
А для меня - новое. Просто, я снапшотами не занимался и даж не задумывался…
С интересом прочитал (и переводил пока читал - мож кому сгодится)

— 25 Сен 2009 в 20:15 ∞ TER
btw,
request.requestHeaders.push(new URLRequestHeader("Cache-Control", "no-cache"));

— 26 Мар 2012 в 05:24 ∞ born если еще актуальна тема для Вас - не могли бы подсказать где тут инициируется сам файл флеш? как подставить свой ролик? спасибо

 

injun

О блоге

Сайт создан в 2006 г. © injun.ru | Seoded.ru — Создание сайта