Блог от AS3Coder'a о JavaScript, HTML, CSS... и немного о Flash.

четверг, 25 марта 2010 г.

Сохранение изображения на ActionScript 3.0

Частенько бывает необходимость сохранить отображаемый во Adobe Flash Player'е контент в изображение. Как это сделать, мы рассмотрим по пунктам:

BitmapData.draw();

Для того, чтобы снять снимок с любого отображаемого объекта (основная их часть находится в пакете flash.display) в ActionScript, нужно воспользоваться методом draw у экземпляра класса flash.display.BitmapData.

Для этого необходимо создать экземпляр класса BitmapData. В конструкторе указываем размеры нашего снимка. Далее вызываем метод draw, где в качестве параметра передадим ссылку на необходимый нам display-объект (в данном случае, это экземпляр сцены).

var raw:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
raw.draw(stage);
После выполнения метода наш экземпляр заполнится сырыми данными с информацией о каждом пикселе.



ImageEncoder

Теперь для того, чтобы наш экземпляр класса BitmapData с сырыми данными стал полноценным изображением, нужно сконвертировать его данные соответсвующим образом и собрать их в файл.

В качестве файла мы используем экземпляр класса flash.utils.ByteArray. В него мы будем записывать сконвертированные данные в виде байтов.

Изображения бывают разных типов. Наиболее популярные из них .png (Portable Network Graphics), .jpg (Joint Photographic Experts Group), .bmp (Bitmap Picture). Отличаются они по алгоритмам сжатия, поэтому в разных типах результат имеет разное качество. На данный момент Encoder'ов изображений на ActionScript 3.0 достаточно, и нет необходимости писать их самим. Поэтому мы воспользуемся готовыми:
В сети также полно Encoder'ов и для других типов изображений.

Пример использования PNGEncoder.as

var brr:ByteArray = PNGEncoder.encode(raw);



FileRerence.save();

Теперь полученный экземпляр класса ByteArray необходимо сохранить в файл на компьютере пользователя. Для решения этой задачи можно воспользоваться методом save экземпляра класса flash.net.FileReference.

В версиях Adobe Flash Player раннее 10, 1.5 этого метода нет. Поэтому приходилось отдавать ByteArray на сервер, который сохранял у себя его в файл и отдавал ссылку на него.

var fil:FileReference = new FileReference();
fil.save(brr, "image.png");

Вот что у меня получилось в качестве примера :)





Смотрите также:

45 комментариев:

  1. Если нужно сохранять большие изображения и/или нужна скорость, то лучше использовать оптимизированные версии энкодеров.
    Вот perfomance-тестинг jpeg энкодера, сделанного на алхимии: http://segfaultlabs.com/devlogs/alchemy-asynchronous-jpeg-encoding
    где-то был еще отличный png энкодер, но сейчас ссылку не могу найти :(

    ОтветитьУдалить
  2. Спасибо за ссылку :) Очень полезная информация.

    ОтветитьУдалить
  3. а можно получить исходник вашего примера?

    ОтветитьУдалить
  4. В ближайшее время я постараюсь подготовить его к публикации, и обязательно выложу его :)

    ОтветитьУдалить
  5. Спасибо, прикольный пример, жаль поздно его нашел :) А реально сохранить набор изображений в видео? Этакое слайдшоу в формате flv.

    ОтветитьУдалить
  6. Да, реально :) Например, FLVRecorder может собирать набор изображений в .flv-файл. Также в сети есть другие примеры.

    ОтветитьУдалить
  7. Извиняюсь за скорость :) Но как и обещал: исходник примера.

    ОтветитьУдалить
  8. други, очень прошу помощи
    у меня восьмой флэш. в его сборку не входи класс flash.utils.ByteArray. перерыл пол-интернета, не могу найти. выложите пожалуйста в доступ, а то задача, описанная в посте стоит, а реализовать не получается..
    заранее очень благодарен)

    ОтветитьУдалить
  9. 8-ой флеш компилирует .swf-файлы под 8-ую версию Flash Player'a. Класс flash.utils.ByteArray поддерживается начиная с 9 версии FlashPlayer'a. Чтобы компилироваться свои приложения под 9-ую версию плеера, вам необходимо использовать Adobe Flash CS3 Proffesional, или более позднюю версию, а там уже ActionScript 3.0 :)

    ОтветитьУдалить
  10. я очень извиняюсь, но установив cs3, а затем и cs4 этого класса не обнаружил. и компилятор ругается, что этот класс не может быть загружен..
    откуда же берется этот загадочный ByteArray?

    ОтветитьУдалить
  11. А вы работаете с ActionScript версии 3.0 или 2.0? Класс ByteArray доступен только для версии 3.0

    ОтветитьУдалить
  12. хм..
    а как понять в какой версии AS я работаю? это опционально что ли?

    ОтветитьУдалить
  13. File > Publish Settings... > Flash > ActionScript version

    ОтветитьУдалить
  14. Спасибо за статью. Можно вопрос. Єсли у меня большой обєкт и он не вмещающийся в экран и скролиться то как его всего полностью без скролбаров передать в битмап? Спасибо заранее.

    ОтветитьУдалить
  15. так а где исходник? по ссылке исходник только swf файл идет

    ОтветитьУдалить
  16. Спасибо за статью.
    Возник вопрос, если необходимо сохранить файл в 8-ми битном БМП. Как быть?

    ОтветитьУдалить
  17. Спасибо за ценный совет))).

    Но уже сам написал. В интернете кстати такой энкодер не смог найти, так что если кому нужен обращайтесь. Поделюсь.)

    ОтветитьУдалить
  18. Всё чудесно, кто знает где скачать энкодер, помогите, плиз!!!

    ОтветитьУдалить
  19. Извиняюсь , только на брел =)
    этот метод только через инет работает?
    а то у меня выдает ошибку ссылаясь на класс кодера, и в кодере заметил html теги =)

    если только через инет . то есть ли как ой нибудь локальный способ, я на шел через BitmapData, но как то фунциклирует как надо=)

    ОтветитьУдалить
  20. Нет, интернет для этого не нужен.
    Нужно подключить в скрипте класс энкодера.
    Классы энкодеров ищите в Google.

    ОтветитьУдалить
  21. спасибо...я вроде нашел... а так большой Уважение вас=)
    только тогда почему вэнкодере который слил у вас .. он пишет html код*?? это мой глюк или как? просто ошибка то выдается на класс png(jpg)encoder...

    ОтветитьУдалить
  22. Потому что это ссылка на HTML-страницу в Google Code, а не на .as-файл :)

    ОтветитьУдалить
  23. Все, спасибо большое . заработало, просто не к тому классу обращался=)

    ОтветитьУдалить
  24. Снова я=) Контрольный вопрс . а как сделать чтобы сохранялись еще динамические данные?
    у мея выводятся данные динамическое тестовое поле... и все сохраняется . только в место введенных данных, получаю их дефолтовые значения?
    это как можно вылечить? или где прочитать про этот косяк?

    ОтветитьУдалить
  25. По сути в качестве изображения сохраняется то, что вы видите на сцене в момент нажатия на кнопку "Сохранить". Проблем с динамическими текстовыми полями я не встречал, поэтому ответить не берусь. Смотрите в Google :)

    ОтветитьУдалить
  26. ggogle шлет в яндекс и наоборот ... то есть у вас не было ни разу проблем? значит косяк у меня ...может что в пятой версии на мудрили... ну ладно .. все спасибо вам =)

    ОтветитьУдалить
  27. А как сделать чтобы в png сохранить с прозрачностью? минуя фон в данном случае ...

    ОтветитьУдалить
  28. Попробуйте указать прозрачность при создании экземпляра класса BitmapData. Инструкции по ссылке.

    ОтветитьУдалить
  29. А как можно сделать чтобы картинка сохранялась без диалога? Т.е. нажал на кнопку сохранить и картинка сохранилась в папке tmp например

    ОтветитьУдалить
  30. Тогда как передать brr в php-скрипт? чтоб сохранить скриптом на сервере

    ОтветитьУдалить
  31. Джентельмены, а есть ли возможность сохранят ьв файл видеопоток? Плеер получает от rtpm сервера живое видео. Можно ли его кроме просмотра ещ еи в файл попутно записывать?..

    ОтветитьУдалить
  32. Здраствуйте

    Я пытаюсь сохранить мувик под именем "big", когда использую только attach , все работает, но когда из "library" добавлаю еще мувики и в них загружаю img, то ничиво не работает, что мне делать помогите

    ОтветитьУдалить
  33. Здраствуйте

    Я пытаюсь сохранить мувик под именем "big", когда использую только attach , все работает, но когда из "library" добавлаю еще мувики и в них загружаю img, то ничиво не работает, что мне делать помогите

    ОтветитьУдалить
  34. Если вы загружаете картинки с других серверов, и хотите снять с них изображение методом BitmapData.draw(), то вы столкнетесь в политикой безопасности Flash Player'a. Подробнее смотрите "Политика безопасности во Flash Player. Наиболее частные столкновения.". Если проблема в другом, опишите подробнее вашу ситуацию.

    ОтветитьУдалить
  35. Безопасность тут не причем, картинки в том же сервере в каком и моя игра.
    С помощью browse загружаю картинку в flash player, например свое лицо, потом перетаскиваю туда другой мувик в котором уже загружано png картинка. все они находятца в мувике big. и питаюсь сохранить этот big createJPG(big, 90, "sketch"); но сохранаетца только первая картинка тоест мое лицо, который я загрузил с помощью browse, а нос или ухо не видно как будто их вобше небыло

    ОтветитьУдалить
  36. Смотрите метод BitmapData.draw() в справке. Ваша проблема происходит именно на этом этапе.

    ОтветитьУдалить
  37. Спасибо огромное. Оказался проблема в allowDomain, хотя и flash и картинки были в одном и том же домене.

    ОтветитьУдалить
  38. Не всегда проблема только в allowDomain, бывает также проблема в отсутствии файла crossdomain.xml.

    этот файл должен лежать в _корне_ того домена, откуда вы загружаете картинку.

    Да, и также при загрузке изображения - не забывайте использовать LoaderContext с флагом checkPolicyFile.

    ...я сталкивался с моментами что домен с www, и без него - флеш считал разными.

    ОтветитьУдалить
  39. А как сделать скрин конкретной области поля?

    ОтветитьУдалить
  40. А можно исходник в fla

    ОтветитьУдалить
  41. Вылаживай исходники

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например <b>, <i>, <a>

Поиск по блогу

Обо мне



Farid Shamsutdinov (AS3Coder)
Russia, Tatarstan, Kazan
as3coder@gmail.com

Подробнее...

Постоянные читатели

© 2014 Farid Shamsutdinov. При копировании материалов, ссылка на источник обязательна. Технологии Blogger.