Use filters for text in GPU AIR mobile mode

Unfortunately, the filters do not work (shadows, glow) in the GPU mode. I am looking for the opportunity to use these effects for text in this mode. I will welcome any advice.

+4
source share
3 answers

As Astraport mentions, you need to draw a text field in bitmapData every time you update text using bitmapData.draw() .

If you use textField.getBounds to determine the size of the required bitmap, then the border rectangle will not include an additional size due to the filter (for example, DropShadowFilter sets the side of the text field to certain pixels depending on the "distance" and "blur"). To ensure filters are enabled when drawing a bitmap, you will also need bitmapData.generateFilterRect() to get the correct rect size.

Code snippet (untested, but general idea):

 // Remember the transform matrix of the text field var offset : Matrix = myTextField.transform.matrix.clone(); // Get the bounds of just the textfield (does not include filters) var tfBounds : Rectangle = myTextField.getBounds( myTextField.parent ); // Create a bitmapData that is used just to calculate the size of the filters var tempBD : BitmpaData = new BitmapData( Math.ceil(tfBounds.width), Math.ceil(tfBounds.height) ); // Make a copy of the textField bounds. We'll adjust this with the filters var finalBounds : rectangle = tfBounds.clone(); // Step through each filter in the textField and adjust our bounds to include them all var filterBounds : rectangle; for each (var filter : BitmapFilter in myTextField.filters) { filterBounds = tempBD.generateFilterRect( tfBounds, filter ); finalBounds.left = Math.min( finalBounds.left, filterBounds.left ); finalBounds.right = Math.max( finalBounds.right, filterBounds.right ); finalBounds.top = Math.min( finalBounds.top, filterBounds.top ); finalBounds.bottom = Math.max( finalBounds.bottom, filterBounds.bottom ); } // Now draw the textfield to a new bitmpaData var textFieldBD : BitmpaData = new BitmapData( Math.ceil(finalBounds.width), math.ceil(finalBounds.height) ); offset.tx = -finalBounds.x; offset.ty = -finalBounds.y; textFieldBD.draw( myTextField.parent, offset, myTextField.transform.colorTransform ); // Create a bitmap and add the bitmap data. Note: normally you would create a // bitmap once and just update the bitmpaData var bitmap : Bitmap = new Bitmap(); myTextField.parent.addChild( bitmap ); // Position the bitmap in same place as textField bitmap.bitmapData = textFieldBD; bitmap.x = myTextField.x - finalBounds.x; bitmap.y = myTextField.y - finalBounds.y; myTextField.visible = false; 
+6
source

Here's how to convert ANY DisplayObject to Bitmap — useful for “recovering” filter effects on an AIR rendermode mobile mobile device. This Pixelthis solution has Pixelthis fixed, optimized and verified:

  // => 'bitmap' must belong to the same parent as 'obj'. 'obj' should be invisible. static public function Update(obj:DisplayObject, bitmap:Bitmap):void { //trace("CacheToBmp",obj.name); // Remember the transform matrix of the text field var offset:Matrix = obj.transform.matrix.clone(); // Get the bounds of just the textfield (does not include filters) var bounds:Rectangle = obj.getBounds(obj); // Create a bitmapData that is used just to calculate the size of the filters var tempBD:BitmapData = new BitmapData( Math.ceil(bounds.width), Math.ceil(bounds.height), false ); bounds.width = obj.width; bounds.height = obj.height; // Make a copy of the textField bounds. We'll adjust this with the filters var finalBounds:Rectangle = new Rectangle(0,0,bounds.width,bounds.height); // Step through each filter in the textField and adjust our bounds to include them all var filterBounds:Rectangle; for each (var filter:BitmapFilter in obj.filters) { filterBounds = tempBD.generateFilterRect( tempBD.rect, filter ); finalBounds = finalBounds.union(filterBounds); } finalBounds.offset(bounds.x,bounds.y); finalBounds.x = Math.floor(finalBounds.x); finalBounds.y = Math.floor(finalBounds.y); finalBounds.width = Math.ceil(finalBounds.width); finalBounds.height = Math.ceil(finalBounds.height); // Now draw the textfield to a new bitmpaData var data:BitmapData = new BitmapData( finalBounds.width, finalBounds.height, false, 0 ); offset.tx = -finalBounds.x; offset.ty = -finalBounds.y; data.drawWithQuality( obj, offset, obj.transform.colorTransform, obj.blendMode, null, true, StageQuality.HIGH ); bitmap.bitmapData = data; // Position the bitmap in same place as 'obj' bitmap.x = obj.transform.matrix.tx + finalBounds.x; bitmap.y = obj.transform.matrix.ty + finalBounds.y; } 
+2
source

The main idea is to apply filters as usual, and then draw a display object in bitmapdata and add a bitmap to the scene. See http://forums.adobe.com/message/3934192 for an example.

If the text that you use for this is static, you need to make it easy enough, but if you want to use this dynamic text (for example, a counter of counters that will change frequently, or text edited by the user) I assume this may start annoying, but I don’t know another solution.

0
source

Source: https://habr.com/ru/post/1434007/


All Articles