How to Solve Image Problems in Flash (for Great Justice)
1. Introduction
For a long time, Macromedia Flash authors have had to deal with this the Flash Player's nasty bitmap problems. A new version (6) has been released now, and its image displaying API seems unchanged; it has the same bitmap problems, and the same tricks are needed.
Because of this, and because I'm tired of seeing people complaining about certain bitmap shifting problems and using really bad solutions (image "margins", decimal positioning, etc) while there's a much better and cleaner one, here's a fast guide explaining the kind of problems Flash has with bitmap images and how to solve them.
This text was wrote sometime on 2002 when Flash MX came out. It was meant to be a longer and more scientific look into what's really wrong, but that's really not needed. In fact, you can skip all the babbling if you need. Also, forgive my broken english at times.
An update on Flash MX 2004 (7), 14-fev-2005: Flash MX 2004 still have bitmap shifting problems - only of a different nature. Please read further (specially near the end of the page) to see what's up with it and how to deal with it.
2. Know Your Enemy
|
The Image |
|
|
Corner zoom 4x |
|
Before giving the solution, I'll try to explain what goes on with image display in flash. For this, I have created a test image: results will be based on its appearance.
This image has everything that will help you notice the errors flash usually has with images. It has a black (100%) outline around it, a brighter (50%) outline inside, it is filled with white, and it has two diagonal strokes. Everything is aliased, so it's a bit easier to see what happened with the image on flash.
Using this image, I did some tests on Flash 6 (Flash 5 and Flash 6 results are the same; Flash 6 was used to point the fact that the image display procedures weren't corrected on the new player version) using the browser version of the player (the standalone version has some minor, rare differences in image displaying - but browser results is what the majority of us need after all).
Also notice that my intention wasn't testing image formats and such, and all images were copied to the clipboard and pasted on Flash (before someone asks, no, they weren't copied as Photoshop objects - which gathers information such as screen resolution and usually messes your image size - but rather as image objects). Pasting images or using imported bitmaps have the same results.
|
2. Results |
|
|
In this example, I've just inserted the image at the movie, checked to make sure their position (X and Y) had no decimal places and tested it on an MSIE 5.5 using Flash Player, latest version. The results are at your right.
At first glance, problems have occured at the border of the images. The border at the top and left sides of the images are stronger than the rest.
Looking at the zoom, you can see what really happens. Flash shifts the image content one pixel down and one pixel right, leaving a trail behind: the original content. Because of this, a pixel disappears from the bottom and right sides, while the top and left sides get one more pixel and column (duplicated). It's important to note that the image does not really change its position; its object corners remain at the same original position. Only the content is shifted down and right.
Using high, medium, and low quality produce the same results. Zooming at 200% also produce the same results, but anything higher will display it correctly.
Test it yourself or download the source file.
3. Launch all Zig
So, what gives? Well, considering it simply shifts the content of the image (save the outmost lines and columns) down and to the right, most people have come with "solutions" like creating an image with a 2 pixel wide transparent margin. While solutions like that should work on some cases, they're just not ok considering they don't stop the shift bug (only make it harder to notice) and sometimes you have to have your image on the same place you have put it on stage (when you have stuff on top of it that needs a pixel on the background to be aligned with a pixel of an object, for example).
There are also some solutions to a problem that happens when using alpha fades. On such cases, the pixel bug will only occur when the image's at 100%; because of that, people people tend to let the image remain at 99% so the pixel shift bug (in this case, seeming like a image trembling) won't be noticed. This solution is also valid in this case, but when you use an image at 99% you tend to make your stage slower if you have animation running near your 99% alpha image.
Well, since Flash 3 or 4 (or something like that) I've noticed something pretty strange, however. While my images had the shifting bug, I noticed that if I created image container movieclips (the "normal" way to use images on Flash) with my axis on the middle of the image (default), sometimes the bug would only occur on half of my image - usually the right side of the image. It's the shifting bug but instead of moving the entire image, it would duplicate a column or line on the middle of the image and shift it to the right or down. This was more noticeable when using vertical or horizontal "shader" lines, and the result was really annoying.
In this case, what I noticed is that the problem didn't occur with the upmost left part of the image: what was in the "negative" area of the movieclip area tended to be rendered right.
|
3. Movie stage axis. The grey area is
where you should put your image. |
|
From that time on, I started praticing something. Whenever I pasted/inserted an image on Flash, I would do the following: select the image, press F8 (to create a symbol), and after the symbol was created, I would go into the symbol and move the image to the "negative area" of the movieclip. That means that, if the image was 200 pixels wide and 100 pixels high, I would move it to (left-corner) -200,-100. That way, all the image would be in the negative area of the movieclip. Using that, I've never had the image shift bug once.
Fortunatelly, Flash 6 has the ability to select where the axis point will be located, so you don't have to edit and move your image around. Simply create your image container with the axis on the lower right corner.
So, what happened? Well, basically, the image shift bug only occurs when your pixels are on a "positive" area, no matter where they are (absolute to the movie stage) but rather, relative to the current image movie.
Repeating my previous example with the "images on negative area" hack: I opened my bug.fla file, created a container mc for all images with the registration axis on the lower right corner.
|
3. Results |
|
|
I don't think any further explanation is necessary: it simply works.
Test it yourself or download the source file.
This solution is so easy and simple - and yet it works virtually all the time - I fail to see why aren't people using it and instead they rely on other weird nonfunctioning solutions. Maybe it only works with me?
4. Dynamically loaded images
Dynamically loaded images - through loadMovie - are an entire different beast. You can't 'change' the axis of a loaded image - you would only be changing the axis of the MovieClip that contains the image. This solution can't be applied to it then.
There's, however, an almost-swift solution to that problem - after loading an image, simple resize just a bit, making it impossible to notice it has been resized. That way, the player will be 'forced' to use more precise values for pixel positioning, and end up rendering the image correctly. This has been suggested by someone else, somewhere else - I have lost the name and the original email, I'm sorry (mail me so I'll credit it here) - and it work wonders even if it resizes your image a bit, making one row and column a bit more transparent.
I, myself, use this code to 'fix' my loaded images (after loading), where 'mc' is the name of my movieclip that contains a loaded image:
this.mc._width = this.mc._width - 0.1;
this.mc._height = this.mc._height - 0.1;
The countereffect result of shrinking the image is hardly noticeable - it only makes the bottom row and righmost column a bit transparent - but it works in fixing the image shifting problem on the rest of the whole content.
5. Flash MX 2004 and the image bug
Flash MX 2004 and Flash Player 7 managed to fix the bitmap shift bug on several cases - specially if the image was a simple static image with its corner on the top left. However, this only applies when exporting as Flash 7 (meaning a SWF version 6 played on Flash Player 7 will still have the original bug, for compatibility), and it also adds new problems - in fact, it just changes the 'bad' area of a movieclip to have an image from the positive area to the negative area of it - so the solution I provide above is actually what will cause the bug in Flash 7! Fortunatelly, Joe Wheeler has published a lengthy investigation on the issue - read it here.
6. End and whatever
I love Flash, believe me. This page is not a bash on the product. It's a guide on how making things work. Not everybody has a keen eye to understand that "HEY the movieclip is cutting the image exactly on the middle of the center axis!!" so this will hopefully help people notice and correct that. Anyways, if you have any correction, suggestion, question or what-will-be about this page, go on and drop me a note throught the email z [AT] zeh.com.br.
- Zeh
|