Текстурированный текст в Actionscript - PullRequest
0 голосов
/ 30 августа 2011

Есть какой-нибудь способ сделать текст "текстурированным" - с результатом, подобным следующему: http://www.entheosweb.com/fireworks/patterned_text.asp

В Flex (так, используя AS3)?

Я думал, что этопростой вопрос, но я застрял: я гуглял по дням и не смог найти способ или обходной путь, чтобы сделать это ...

Ответы [ 3 ]

3 голосов
/ 30 августа 2011

Грубая идея такова:

  • Создайте TextField с любым шрифтом, который вам нужен, и напишите там любой текст, который вам нужен.
  • Создайте новый объект BitmapData и draw() TextField, чтобы получить его растровое представление.
  • Получите вашу текстуру как объект BitmapData (если вы загрузите в JPG, он будет в растровом изображении, которое вы получите после загрузки)
  • Создайте новый объект BitmapData и используйте copyPixels() для рисования текстуры, в то время как первый объект BitmapData (скрытый TextField) используется в качестве альфа-маски: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#copyPixels()
  • Вуаля, текстурированный текст.

Дайте мне знать, если вам нужен код, но он должен быть довольно простым

Редактировать с кодом:

package  
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;

    public class TestTexturedText extends Sprite
    {
        private var m_text:TextField        = null;         // the TextField that we use to write our text
        private var m_texture:BitmapData    = null;         // the texture that we're going to texture our TextField with
        private var m_textBMD:BitmapData    = null;         // the BitmapData that we use to draw our TextField
        private var m_drawPoint:Point       = new Point;    // Point used in drawing the final BitmapData
        private var m_drawRect:Rectangle    = new Rectangle;// the Rectangle we use to determine which part of the texture to take

        // the texture we're using
        [Embed(source="texture.jpg")]
        private var m_textureImage:Class;

        public function TestTexturedText() 
        {
            this._createText( "Trebuchet Ms", 50.0 );   // create our textfield
            this._getTexture();                         // get our texture

            // create textured text 1
            var bmd:BitmapData = this.getTexturedText( "hello world" );
            var b:Bitmap = new Bitmap( bmd );
            b.x = 250.0;
            b.y = 50.0;
            this.addChild( b );

            // create textured text 2
            bmd = this.getTexturedText( "testing" );
            b = new Bitmap( bmd );
            b.x = 250.0;
            b.y = 100.0;
            this.addChild( b );
        }

        /**
         * Get a BitmapData of the text we want, textured
         * @param text The text we're looking at
         * @param randomPos Should we take a random position from our text, or just start at (0,0)?
         * @return A BitmapData object containing our textured text
         */
        public function getTexturedText( text:String, randomPos:Boolean = true ):BitmapData
        {
            // set the text
            this.m_text.text    = text;
            var tw:int          = int( this.m_text.width + 0.5 ); // quick conver to int without clipping
            var th:int          = int( this.m_text.height + 0.5 );

            // reuse our previous BitmapData if we can, rather than always creating a new one
            if ( this.m_textBMD == null || this.m_textBMD.width < tw || this.m_textBMD.height < th )
                this.m_textBMD = new BitmapData( tw, th, true, 0x00000000 );
            else
                this.m_textBMD.fillRect( this.m_textBMD.rect, 0x00000000 ); // clear the bitmapdata of the old rendering

            // draw our text
            this.m_textBMD.draw( this.m_text, null, null, null, null, true );

            // set our draw rect position
            this.m_drawRect.x       = ( randomPos ) ? Math.random() * ( this.m_texture.width - tw ) : 0.0;
            this.m_drawRect.y       = ( randomPos ) ? Math.random() * ( this.m_texture.height - tw ) : 0.0;
            this.m_drawRect.width   = tw;
            this.m_drawRect.height  = th;

            // get a new bitmap data (that we'll return) and copy our pixels, using the first bmd as an alpha mask
            var ret:BitmapData = new BitmapData( tw, th, true, 0x00000000 );
            ret.copyPixels( this.m_texture, this.m_drawRect, this.m_drawPoint, this.m_textBMD, this.m_drawPoint );
            return ret;
        }

        // creates the TextField that we'll use to write our text
        private function _createText( font:String, size:Number ):void
        {
            var tf:TextFormat               = new TextFormat( font, size );
            this.m_text                     = new TextField;
            this.m_text.defaultTextFormat   = tf;
            this.m_text.autoSize            = TextFieldAutoSize.LEFT;

            // debug add it to the stage
            this.m_text.x = 250.0;
            this.addChild( this.m_text );
        }

        // gets the texture that we'll use to create our text
        private function _getTexture():void
        {
            this.m_texture = ( ( new this.m_textureImage ) as Bitmap ).bitmapData;

            // debug add it to the stage
            var debug:Bitmap = new Bitmap( this.m_texture );
            debug.scaleX = debug.scaleY = 0.2;
            this.addChild( debug );
        }

    }

}

Некоторые баллы:

  • Потребуется небольшая работа, чтобы превратить его в класс - это основной класс (как я использую его для запуска приложения)
  • Отредактируйте вложение m_textureImage, чтобы указать на текстуру, которую вы хотите использовать, или, в качестве альтернативы, загрузите одну.
  • Просто вызовите функцию getTexturedText(), чтобы получить BitmapData с нужным вам текстом
  • Вы можете удалить место, где я добавляю различные элементы (текстуру, текстовое поле, результат) на сцену. Это просто, чтобы показать вам, что происходит
  • Это чистый AS3, но он также будет работать в flex
1 голос
/ 30 августа 2011

Прошло много времени с тех пор, как я использовал ActionScript, но я мог дать некоторые идеи.

  • Самое простое решение, о котором я могу подумать, - это загрузить изображение в спрайт, а затем замаскировать его, используя другой спрайт со встроенным текстом.

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

0 голосов
/ 30 августа 2011

Как уже отвечали другие, используя текст в качестве маски для изображения, можно добиться этого во Flash или Flex.

Хороший ответ от divillysausages, но, поскольку вы комментируете там, что вас смущает отсутствие разметки Flex в этом примере, вот минимальный пример разметки MXML:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application creationComplete="img.mask=txt" xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Canvas>
        <mx:Text id="txt" cacheAsBitmap="true" fontSize="48" fontWeight="bold" text="LOREM IPSUM" />
        <mx:Image id="img" cacheAsBitmap="true" autoLoad="true" source="http://farm3.static.flickr.com/2783/4092743591_3fb90fa599.jpg" />
    </mx:Canvas>
</mx:Application>

Принцип такой же, как и в других ответах, текст должен быть растровым, чтобы использоваться в качестве маски для изображения (здесь достигается с помощью cacheAsBitmap = "true").

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...