Gamua / Starling-Framework

The Cross Platform Game Engine
http://www.starling-framework.org
Other
2.82k stars 821 forks source link

How do I use it correctly “drawToBitmapData” #1078

Closed renjiancheng closed 3 years ago

renjiancheng commented 3 years ago

hi,I am a green hand of as3.When I was developing products using Starling,i get a problem ,that i must use the api "drawToBitmapData"of class DisplayObject to finish cropping the picture . but when I do not pass the first parameter "out", the bitMapdata returned is not the same width and height as the original image, and they are usually truncated.

private function cutImageDemo(tar:Image):void {
  trace(tar.width,tar.height);
  originalBitMapData=tar.drawToBitmapData();
  var img:Image=new Image(Texture.fromBitmapData(originalBitMapData));
  trace(img.width,img.height);
  img.scale=Config.stageRealW/img.width;
  this.addChild(img);
}

that i got 1.png

out:  1280 640   1170 585;

When I pass a bitMapData for the first parameter that I want, the bitMapData returned is actually the bitMapData That I want, but it contains a lot of blank pixels! I noticed that it might have something to do with the width and height of the AIR, but I didn't draw any conclusions. Since I can find blogs on this topic on the Internet, there are almost no blogs, so can you help me qvq.

private function cutImageDemo(tar:Image):void {
    trace(tar.width,tar.height);
    originalBitMapData=new BitmapData(tar.width,tar.height);
    originalBitMapData=tar.drawToBitmapData(originalBitMapData);
    var img:Image=new Image(Texture.fromBitmapData(originalBitMapData));
    trace(img.width,img.height);
    img.scale=Config.stageRealW/img.width;
    this.addChild(img);
}

that i got 2.png

​ out: 1280 640 1280 640

JohnBlackburne commented 3 years ago

Have you looked at using a RenderTexture? For what you want to do it should be able to do it, and it has the advantage of being much much faster - drawing to a BitmapData is about the slowest graphics operation there is.

A RenderTexture also works very straightforwardly, while drawing to BitmapData has known bugs such as this:

https://github.com/Gamua/Adobe-Runtime-Support/issues/392

It does not sound like the same bug but the underlying drawing routine which it relies on has bugs on some platforms.

The RenderTexture sample code (for the Starling sample on the website) is here

PrimaryFeather commented 3 years ago

Having a look at the RenderTexture class is definitely a good idea, as John suggested! If you can live with its downsides (mainly that it's corrupted when the context is lost, and that you cannot read any pixel data), then this is definitely the preferred way.

However, your problem is most likely connected to the contentScaleFactor Starling is using. My guess is that the stage size is not equal to the viewport size. DisplayObject.drawToBitmapData always draws in the best possible resolution – and with a contentScaleFactor different to 1.0, this means that not all of the pixels will fit into the BitmapData instance.

Please try the following:

var scale:Number = Starling.current.contentScaleFactor;
originalBitMapData=new BitmapData(tar.width * scale, tar.height * scale);
// ...

I think that should do the trick!

renjiancheng commented 3 years ago

It doesn't seem to work for me to try ‘Starling.current.contentScaleFacto’. I'm looking at render texture right now. Thank you, John

PrimaryFeather commented 3 years ago

Hm, that's weird. There's another, internal scale factor you could try: Starling.painter.backBufferScaleFactor — if that's not it, either, then I'd need a standalone example to check out what's going on.

But, in any case, using RenderTexture would definitely be the preferred way to go, anyway.

renjiancheng commented 3 years ago

I finished the function with rendertexture. Thank you

PrimaryFeather commented 3 years ago

Congrats! Happy to hear that. 😁