3

Here's my problem, I need to scale and clip images into square sized tiles to put into a tile list. Here's how I want it to work:

  1. I want all my tiles to be, say, 300px x 300px.

  2. For each image, I want to scale the shorter side (either width or height) to fit in the tile using the "letterbox" scaleMode (so that it maintains aspect ratio).

  3. Then I want to position the image in the center and clip away anything left over from either both sides or the top and bottom.

Here's an example to help clarify:

  • I have an image with width=600px and height=1200px. First I want to scale the image to width=300px and height=600px (notice that aspect ratio is maintained), then center the image vertically and clip the image to 300 x 300.

Is this possible? This is actually a pretty standard way of displaying square thumbnails in many photo-based web sites, but I can't find a way to make it work in flex.

Any help would be appreciated, thanks!

UPDATE JUNE 2012:

Just in case anyone finds this thread now, this issue has been resolved in the latest version of the Flex SDK. On the spark image object there is a new scaleMode of "zoom" which does exactly what I've asked for here.

Andy
  • 4,475
  • 4
  • 19
  • 20

1 Answers1

2

Take your big image and draw it on BitmapData with scale and reposition:

const zoom:Number = Math.max(THUMB_WIDTH/image.width, THUMB_HEIGHT/image.height);
const x:int = (THUMB_WIDTH - image.width*zoom)/2;
const y:int = (THUMB_HEIGHT - image.height*zoom)/2;
var matrix:Matrix = new Matrix;
matrix.scale(zoom, zoom);
matrix.translate(x, y);

var _thumbBitmap:BitmapData = new BitmapData(THUMB_WIDTH, THUMB_HEIGHT, false, 0xFFFFFF);
_thumbBitmap.draw(image, matrix, null, null, null, true);

Then assign resulting BitmapData to the source of the BitmapImage.

More: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#draw%28%29 http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/primitives/BitmapImage.html#source

moropus
  • 3,672
  • 1
  • 22
  • 30
  • Thanks for this wonderful and very helpful piece of coding. Only two small quibbles: 1) We need to use Math.max and not Math.min, otherwise the whole image is fit into the thumbnail. 2) Also, the matrix.translate must be applied after the scale, otherwise the image will not center correctly. Other than that, it works wonderfully. – Andy Aug 30 '11 at 09:44
  • Ok, that's usefull notes, I edited the answer. Please don't forget to check answer as correct, if you find it helpful. – moropus Aug 30 '11 at 09:51
  • Any chance you could show me how to extend the Image class so that I can add a new scaleMode called "fillAndClip", and draw it like this? I would really appreciate it... :-) – Andy Aug 31 '11 at 17:55
  • @tom__26, you should override two protected methods - `measure` and `updateDisplayList`. The first one calculates the size of the ui object, the second - applies changes and draws resulting image. Look at the `BitmapImage` source, it's not complicated and quite straightforward. – moropus Sep 01 '11 at 07:07
  • Thanks, I'll try it. I just hope I can override the Inspectable property "scaleMode" so that I can add another value.... I'm still kind of new to flex :-) – Andy Sep 01 '11 at 09:05
  • awesome - google got me here, but stackoverflow was here to get to :) Thanks for the code man, this is going to be a massively humonstrous help! – Thomas Wright Jun 21 '13 at 18:15