Hi,
I created a test application like:
openfl create DisplayingABitmap
And put my test code there. It looks like:
package;
import openfl.display.Bitmap;
import openfl.display.BitmapData;
import openfl.display.DisplayObject;
import openfl.display.DisplayObjectContainer;
import openfl.display.Sprite;
import openfl.events.Event;
import openfl.events.MouseEvent;
import openfl.filters.BitmapFilter;
import openfl.filters.ColorMatrixFilter;
import openfl.geom.ColorTransform;
import openfl.geom.Point;
import openfl.geom.Rectangle;
import openfl.Assets;
class Main extends Sprite {
private static var FILTER_BLACK_WHITE : ColorMatrixFilter = new ColorMatrixFilter([1 / 3, 1 / 3, 1 / 3, 0, 0, 1 / 3, 1 / 3, 1 / 3, 0, 0, 1 / 3, 1 / 3, 1 / 3, 0, 0, 0, 0, 0, 1, 0]);
private var bitmap: Bitmap;
private var cachedBitmapData: BitmapData;
private var active: Bool;
public function new () {
super();
bitmap = new Bitmap(Assets.getBitmapData("assets/openfl.png"));
active = false;
addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
invalidateCachedBitmap();
}
private function invalidateCachedBitmap(): Void {
removeEventListener(Event.ENTER_FRAME, createCachedBitmap);
addEventListener(Event.ENTER_FRAME, createCachedBitmap);
}
public static function renderToBitmapData(object: DisplayObject, point: Point = null): BitmapData {
// TODO: *****, avoid using matrix to transform image into bitmap data coordinate space as there is a bug with openfl
// no scale yet
// no rotation yet
var _x: Float = object.x;
var _y: Float = object.y;
var objectColorTransform: ColorTransform = object.transform.colorTransform;
var bounds: Rectangle;
var bitmapData: BitmapData;
bounds = object.getBounds(object.parent);
bounds.x = Math.floor(bounds.x);
bounds.y = Math.floor(bounds.y);
bounds.height = Math.ceil(bounds.height);
bounds.width = Math.ceil(bounds.width);
var realBounds: Rectangle = new Rectangle(0, 0, bounds.width, bounds.height);
if (object.filters.length > 0) {
var objectFilters: Array<BitmapFilter> = object.filters;
var tmpBitmapData: BitmapData;
var filterRect: Rectangle;
tmpBitmapData = new BitmapData(Std.int(realBounds.width), Std.int(realBounds.height), false);
filterRect = tmpBitmapData.generateFilterRect(tmpBitmapData.rect, objectFilters[0]);
tmpBitmapData.dispose();
for (i in 1...objectFilters.length){
tmpBitmapData = new BitmapData(Std.int(filterRect.width), Std.int(filterRect.height), true, 0);
filterRect = tmpBitmapData.generateFilterRect(tmpBitmapData.rect, objectFilters[i]);
realBounds = realBounds.union(filterRect);
tmpBitmapData.dispose();
}
}
realBounds.offset(bounds.x, bounds.y);
realBounds.width = Math.max(realBounds.width, 1);
realBounds.height = Math.max(realBounds.height, 1);
if (Std.is(object, DisplayObjectContainer) == true) {
var objectDisplayObjectContainer: DisplayObjectContainer = cast(object, DisplayObjectContainer);
for (i in 0...objectDisplayObjectContainer.numChildren) {
var childObject: DisplayObject = objectDisplayObjectContainer.getChildAt(i);
childObject.x-= realBounds.x;
childObject.y-= realBounds.y;
}
}
bitmapData = new BitmapData(Std.int(realBounds.width), Std.int(realBounds.height), true, 0);
bitmapData.draw(object, null, objectColorTransform);
if (Std.is(object, DisplayObjectContainer) == true) {
var objectDisplayObjectContainer: DisplayObjectContainer = cast(object, DisplayObjectContainer);
for (i in 0...objectDisplayObjectContainer.numChildren) {
var childObject: DisplayObject = objectDisplayObjectContainer.getChildAt(i);
childObject.x+= realBounds.x;
childObject.y+= realBounds.y;
}
}
realBounds.offset(-_x, -_y);
if (point != null) {
point.setTo(realBounds.x, realBounds.y);
}
return bitmapData;
}
private function createCachedBitmap(event: Event): Void {
trace("createCachedBitmap()");
while (numChildren > 0) removeChildAt(0);
if (active == true) {
bitmap.filters = [];
} else {
bitmap.filters = [FILTER_BLACK_WHITE];
}
var bitmapPoint : Point = new Point();
if (cachedBitmapData != null) cachedBitmapData.dispose();
cachedBitmapData = renderToBitmapData(bitmap, bitmapPoint);
bitmap.filters = [];
var sprite: Sprite = new Sprite();
var button: DisplayObject = new Bitmap(cachedBitmapData);
sprite.buttonMode = active;
sprite.x = bitmapPoint.x;
sprite.y = bitmapPoint.y;
sprite.addChild(button);
addChild(sprite);
removeEventListener(Event.ENTER_FRAME, createCachedBitmap);
}
private function onMouseUp(event: MouseEvent) {
trace("onMouseUp()");
active = !active;
invalidateCachedBitmap();
}
}
Unfortunately I can not test as the program crashes with:
Andreass-Air:bitmapdata-draw-issues andreas$ openfl test neko -debug 2>&1
Called from openfl.filters.ColorMatrixFilter::$statics line 16
Called from openfl.filters._ColorMatrixFilter.ColorMatrixShader::$init line 138
Called from a C function
Called from openfl.filters._ColorMatrixFilter.ColorMatrixShader::new line 177
Called from openfl.display.Shader::get_data line 691
Called from openfl.display.Shader::__init line 259
Called from openfl.display.Shader::__initGL line 284
Called from openfl.display.Shader::__processGLData line 453
Called from EReg::matchedPos line 62
Uncaught exception - Invalid call
Is it possible that this crash is related to latest release?
(I edited the source code to remove previous attached Childs)
Best regards
Andreas