Copy link to clipboard
Copied
Hello guys, how are you?
I'm trying to create an actionscript 3 class that receives an external image, adds it into a movieclip and adjusts it without corrupting the aspect ratio of the image.
I've tried working with BitmapData and Bitmap only, but can not hit the calculations. Can anyone help me?
Thank you,
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.PixelSnapping;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.system.LoaderContext;
public class PhotoHolder extends MovieClip
{
private var _loader:Loader;
public function PhotoHolder()
{
}
public function loadPhoto(urlImg:String):void
{
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
_loader.load(new URLRequest(urlImg));
}
private function onError(e:IOErrorEvent):void
{
trace("ERROR!");
}
private function onComplete(e:Event):void
{
var loadedImage:Bitmap = Bitmap(_loader.content);
var bmd:BitmapData = new BitmapData(_loader.content.width, _loader.content.height, true);
bmd.draw(loadedImage, null);
this.holder.addChild(createBitmap(bmd));
}
private function createBitmap(bmd:BitmapData):Bitmap
{
var bitmap:Bitmap = new Bitmap(bmd);
bitmap.smoothing = true;
setSize(bitmap, bmd.width, bmd.height, this.holder.x, this.holder.y);
return bitmap;
}
private function setSize(target:DisplayObject, contentWidth:Number, contentHeight:Number, targetWidth:Number, targetHeight:Number):void
{
var w:Number = targetWidth;
var h:Number = targetHeight;
// maintain aspect ratio
var containerRatio:Number = targetWidth / targetHeight;
var imageRatio:Number = contentWidth / contentHeight;
if (containerRatio < imageRatio) h = w / imageRatio;
else w = h * imageRatio;
target.width = w;
target.height = h;
//centre content - this might change based on your setup
target.x = (targetWidth - w) * .5;
target.y = (targetHeight -h) * .5;
}
}
}
Copy link to clipboard
Copied
what's the problem?
Copy link to clipboard
Copied
in this line you use the holder position to set the content width/height:
setSize(bitmap, bmd.width, bmd.height, this.holder.x, this.holder.y);
so if your holder sits at 0/0
your setSize function produces a problem
var imageRatio:Number = contentWidth / contentHeight;
because dividing through 0 is not allowed.
You probably meant to write: (bitmap, bmd.width, bmd.height, this.holder.width, this.holder.height); ?
Copy link to clipboard
Copied
You´re right. I made a mistake when I changed some parameters to post the class here. The original is like your sample (bitmap, bmd.width, bmd.height, this.holder.width, this.holder.height);
The problem is: When I resize the image to holders properties, the image loses its aspect ratio. There´s a way to fix it?
Copy link to clipboard
Copied
the decisive line is this:
this.holder.addChild(createBitmap(bmd));
assuming your holder is some kind of MovieClip that is present on Stage.
the moment your bitmap is added to the holder it will inherit its scaling properties.
If you only want to use the holder clip as a container to hold the bitmap its important that its scaling properties are set identical.
It doesn`t matter if it is 1px/1px or 1920px/1080px, important is that his scaleX/scaleY ratio is 1.0 (even a 1920*1080 rectangle converted to a MovieClip will have a scaleX/scaleY ratio of 1.0 as long as you zoom it uniformally.
Your calculation is in my opinion not really necessary.
What happens if you make this line in a comment inside your createBitmap function:
//setSize(bitmap, bmd.width, bmd.height, this.holder.width, this.holder.height);
?
If your bitmap is still distorted it means your holder Movieclip is distorted.
Copy link to clipboard
Copied
You´re right! It´s happening, the case is my movieclip. I will think about it. I made fell changes in the class, it´s more easy to read. Now, that is the principal methods:
private function onComplete(e:Event):void
{
var w:Number = this.width;
var h:Number = this.height;
var loadedImage:Bitmap = Bitmap(_loader.content);
_ratio = _loader.content.height / _loader.content.width;
this.addChild(resizeIt(loadedImage, w, h));
}
private function resizeIt(bitmap:Bitmap, maxW:Number, maxH:Number):Bitmap
{
if (bitmap.width > maxW)
{
bitmap.width = maxW;
bitmap.height = bitmap.width * _ratio;
}
if (bitmap.height > maxH)
{
bitmap.height = maxH;
bitmap.width = bitmap.height / _ratio;
}
bitmap.smoothing = true;
return bitmap;
}
}
But I have one more question:
I'm reducing the size of the image to place it in the container. I'm not using scaleX and scaleY. How do I fill the container without losing image quality?
Copy link to clipboard
Copied
With "image quality" I suppose you mean, that the Bitmap.smoothing is not applied, and that the Bitmap looks pixelated?