Resizing Image from a decoded ByteArray

apache-flexbytearrayimageresize

I am trying to display a bytearray as a resized image. The Image is displaying correctly, but the sizing is off. Let me explain.

First I have the image data encoded so I need to decode the image data

// Instantiate decoder
var decoder:Base64Decoder = new Base64Decoder();
// Decode image data
decoded.decode(picture.data);
// Export data as a byteArray
var byteArray:ByteArray = decoder.toByteArray();
// Display image
var img:Image = new Image();
img.load(byteArray);

This works. The image is displayed correctly. However, if I hardcode the image (img) height the resized image is shown correctly, but within a box with the original image's dimensions.

For example, if the original image has a height of 300px and a width of 200px and the img.height property is set to 75; the resized image with height of 75 is shown correctly. But the resized image is shown in the upper left corner of the img container that is still set to a height of 300px and a width of 200px. Why does it do that? And what is the fix?

The best way to illustrate the problem is by placing the image inside a VBox and show the borders of the VBox. From the code block above, if I change the image height and set the image to maintain aspect ratio (which by default is set to true but I add it here for completeness). the problem becomes clear.

// Display image
var img:Image = new Image();
img.height = 75; // Hardcode image height (thumbnail)
img.maintainAspectRatio = true;
img.load(byteArray);
// Encapsulate the image inside a VBox to illustrate the problem
var vb:VBox = new VBox();
vb.setStyle('borderStyle', 'solid');
vb.setStyle('borderColor', 'red');
vb.setStyle('borderThickness', 2);
vb.addChild(img);

I have been working on this problem for days and cannot come up with a solution. Any ideas? What am I missing?

Best Answer

The workaround I used is as follows:

I created an event listener for the img display object. Then after the img has loaded, I manually set the height and width of the image. I know what I want the height (preHeight) to be so that is hardcoded. I then calculate the width and set that as the image width. For some reason I had to use the explicitHeight and explicitWidth properties to finally get the sizing right.

I hope this helps someone.

img.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);

private function onCreationComplete(event:FlexEvent) : void
{
  img.addEventListener(Event.COMPLETE, onImageLoadComplete);
}

private function onImageLoadComplete(event:Event) : void
{
    var image:Image = event.currentTarget as Image;
    var preHeight:Number = 0;
    var h:uint = Bitmap(image.content).bitmapData.height;
    var w:uint = Bitmap(image.content).bitmapData.width;

    // Check height
    preHeight = h > 170 ? 170 : h;
    // Set the width
    img.explicitWidth = (preHeight * w)/h;
    img.explicitHeight = preHeight; 
}