Частенько бывает необходимость сохранить отображаемый во Adobe Flash Player'е контент в изображение. Как это сделать, мы рассмотрим по пунктам:
BitmapData.draw();
Для того, чтобы снять снимок с любого отображаемого объекта (основная их часть находится в пакете flash.display) в ActionScript, нужно воспользоваться методом draw у экземпляра класса flash.display.BitmapData.
Для этого необходимо создать экземпляр класса BitmapData. В конструкторе указываем размеры нашего снимка. Далее вызываем метод draw, где в качестве параметра передадим ссылку на необходимый нам display-объект (в данном случае, это экземпляр сцены).
После выполнения метода наш экземпляр заполнится сырыми данными с информацией о каждом пикселе.
ImageEncoder
Теперь для того, чтобы наш экземпляр класса BitmapData с сырыми данными стал полноценным изображением, нужно сконвертировать его данные соответсвующим образом и собрать их в файл.
В качестве файла мы используем экземпляр класса flash.utils.ByteArray. В него мы будем записывать сконвертированные данные в виде байтов.
Изображения бывают разных типов. Наиболее популярные из них .png (Portable Network Graphics), .jpg (Joint Photographic Experts Group), .bmp (Bitmap Picture). Отличаются они по алгоритмам сжатия, поэтому в разных типах результат имеет разное качество. На данный момент Encoder'ов изображений на ActionScript 3.0 достаточно, и нет необходимости писать их самим. Поэтому мы воспользуемся готовыми:
Пример использования PNGEncoder.as
FileRerence.save();
Теперь полученный экземпляр класса ByteArray необходимо сохранить в файл на компьютере пользователя. Для решения этой задачи можно воспользоваться методом save экземпляра класса flash.net.FileReference.
В версиях Adobe Flash Player раннее 10, 1.5 этого метода нет. Поэтому приходилось отдавать ByteArray на сервер, который сохранял у себя его в файл и отдавал ссылку на него.
Вот что у меня получилось в качестве примера :)
Смотрите также:
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 достаточно, и нет необходимости писать их самим. Поэтому мы воспользуемся готовыми:
- PNGEncoder.as (Во Flex 4 этот класс входит в стандартную поставку от Adobe)
- JPGEncoder.as (Во Flex 4 этот класс входит в стандартную поставку от Adobe)
- BMPEncoder.as
Пример использования 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");
Вот что у меня получилось в качестве примера :)
Смотрите также:
Если нужно сохранять большие изображения и/или нужна скорость, то лучше использовать оптимизированные версии энкодеров.
ОтветитьУдалитьВот perfomance-тестинг jpeg энкодера, сделанного на алхимии: http://segfaultlabs.com/devlogs/alchemy-asynchronous-jpeg-encoding
где-то был еще отличный png энкодер, но сейчас ссылку не могу найти :(
Спасибо за ссылку :) Очень полезная информация.
ОтветитьУдалитьа можно получить исходник вашего примера?
ОтветитьУдалитьВ ближайшее время я постараюсь подготовить его к публикации, и обязательно выложу его :)
ОтветитьУдалитьСпасибо, прикольный пример, жаль поздно его нашел :) А реально сохранить набор изображений в видео? Этакое слайдшоу в формате flv.
ОтветитьУдалитьДа, реально :) Например, FLVRecorder может собирать набор изображений в .flv-файл. Также в сети есть другие примеры.
ОтветитьУдалитьИзвиняюсь за скорость :) Но как и обещал: исходник примера.
ОтветитьУдалитьдруги, очень прошу помощи
ОтветитьУдалитьу меня восьмой флэш. в его сборку не входи класс flash.utils.ByteArray. перерыл пол-интернета, не могу найти. выложите пожалуйста в доступ, а то задача, описанная в посте стоит, а реализовать не получается..
заранее очень благодарен)
8-ой флеш компилирует .swf-файлы под 8-ую версию Flash Player'a. Класс flash.utils.ByteArray поддерживается начиная с 9 версии FlashPlayer'a. Чтобы компилироваться свои приложения под 9-ую версию плеера, вам необходимо использовать Adobe Flash CS3 Proffesional, или более позднюю версию, а там уже ActionScript 3.0 :)
ОтветитьУдалитья очень извиняюсь, но установив cs3, а затем и cs4 этого класса не обнаружил. и компилятор ругается, что этот класс не может быть загружен..
ОтветитьУдалитьоткуда же берется этот загадочный ByteArray?
А вы работаете с ActionScript версии 3.0 или 2.0? Класс ByteArray доступен только для версии 3.0
ОтветитьУдалитьхм..
ОтветитьУдалитьа как понять в какой версии AS я работаю? это опционально что ли?
File > Publish Settings... > Flash > ActionScript version
ОтветитьУдалитьСпасибо за статью. Можно вопрос. Єсли у меня большой обєкт и он не вмещающийся в экран и скролиться то как его всего полностью без скролбаров передать в битмап? Спасибо заранее.
ОтветитьУдалитьтак а где исходник? по ссылке исходник только swf файл идет
ОтветитьУдалитьПростите за ошибку :( Вот исходник
ОтветитьУдалитьСпасибо за статью.
ОтветитьУдалитьВозник вопрос, если необходимо сохранить файл в 8-ми битном БМП. Как быть?
Ищите Encoder :)
ОтветитьУдалитьСпасибо за ценный совет))).
ОтветитьУдалитьНо уже сам написал. В интернете кстати такой энкодер не смог найти, так что если кому нужен обращайтесь. Поделюсь.)
Всё чудесно, кто знает где скачать энкодер, помогите, плиз!!!
ОтветитьУдалитьИзвиняюсь , только на брел =)
ОтветитьУдалитьэтот метод только через инет работает?
а то у меня выдает ошибку ссылаясь на класс кодера, и в кодере заметил html теги =)
если только через инет . то есть ли как ой нибудь локальный способ, я на шел через BitmapData, но как то фунциклирует как надо=)
Нет, интернет для этого не нужен.
ОтветитьУдалитьНужно подключить в скрипте класс энкодера.
Классы энкодеров ищите в Google.
спасибо...я вроде нашел... а так большой Уважение вас=)
ОтветитьУдалитьтолько тогда почему вэнкодере который слил у вас .. он пишет html код*?? это мой глюк или как? просто ошибка то выдается на класс png(jpg)encoder...
Потому что это ссылка на HTML-страницу в Google Code, а не на .as-файл :)
ОтветитьУдалитьВсе, спасибо большое . заработало, просто не к тому классу обращался=)
ОтветитьУдалитьСнова я=) Контрольный вопрс . а как сделать чтобы сохранялись еще динамические данные?
ОтветитьУдалитьу мея выводятся данные динамическое тестовое поле... и все сохраняется . только в место введенных данных, получаю их дефолтовые значения?
это как можно вылечить? или где прочитать про этот косяк?
По сути в качестве изображения сохраняется то, что вы видите на сцене в момент нажатия на кнопку "Сохранить". Проблем с динамическими текстовыми полями я не встречал, поэтому ответить не берусь. Смотрите в Google :)
ОтветитьУдалитьggogle шлет в яндекс и наоборот ... то есть у вас не было ни разу проблем? значит косяк у меня ...может что в пятой версии на мудрили... ну ладно .. все спасибо вам =)
ОтветитьУдалитьА как сделать чтобы в png сохранить с прозрачностью? минуя фон в данном случае ...
ОтветитьУдалитьПопробуйте указать прозрачность при создании экземпляра класса BitmapData. Инструкции по ссылке.
ОтветитьУдалитьА как можно сделать чтобы картинка сохранялась без диалога? Т.е. нажал на кнопку сохранить и картинка сохранилась в папке tmp например
ОтветитьУдалитьВо FlashPlayer никак :( В AIR можно :)
ОтветитьУдалитьТогда как передать brr в php-скрипт? чтоб сохранить скриптом на сервере
ОтветитьУдалитьНапример, используя Multipart URLLoader Class
ОтветитьУдалитьДжентельмены, а есть ли возможность сохранят ьв файл видеопоток? Плеер получает от rtpm сервера живое видео. Можно ли его кроме просмотра ещ еи в файл попутно записывать?..
ОтветитьУдалитьЗдраствуйте
ОтветитьУдалитьЯ пытаюсь сохранить мувик под именем "big", когда использую только attach , все работает, но когда из "library" добавлаю еще мувики и в них загружаю img, то ничиво не работает, что мне делать помогите
Здраствуйте
ОтветитьУдалитьЯ пытаюсь сохранить мувик под именем "big", когда использую только attach , все работает, но когда из "library" добавлаю еще мувики и в них загружаю img, то ничиво не работает, что мне делать помогите
Если вы загружаете картинки с других серверов, и хотите снять с них изображение методом BitmapData.draw(), то вы столкнетесь в политикой безопасности Flash Player'a. Подробнее смотрите "Политика безопасности во Flash Player. Наиболее частные столкновения.". Если проблема в другом, опишите подробнее вашу ситуацию.
ОтветитьУдалитьБезопасность тут не причем, картинки в том же сервере в каком и моя игра.
ОтветитьУдалитьС помощью browse загружаю картинку в flash player, например свое лицо, потом перетаскиваю туда другой мувик в котором уже загружано png картинка. все они находятца в мувике big. и питаюсь сохранить этот big createJPG(big, 90, "sketch"); но сохранаетца только первая картинка тоест мое лицо, который я загрузил с помощью browse, а нос или ухо не видно как будто их вобше небыло
Смотрите метод BitmapData.draw() в справке. Ваша проблема происходит именно на этом этапе.
ОтветитьУдалитьСпасибо огромное. Оказался проблема в allowDomain, хотя и flash и картинки были в одном и том же домене.
ОтветитьУдалитьНе всегда проблема только в allowDomain, бывает также проблема в отсутствии файла crossdomain.xml.
ОтветитьУдалитьэтот файл должен лежать в _корне_ того домена, откуда вы загружаете картинку.
Да, и также при загрузке изображения - не забывайте использовать LoaderContext с флагом checkPolicyFile.
...я сталкивался с моментами что домен с www, и без него - флеш считал разными.
А как сделать скрин конкретной области поля?
ОтветитьУдалитьА можно исходник в fla
ОтветитьУдалитьВылаживай исходники
ОтветитьУдалить