Polar Distortion like PhotoShop in AS3

At some point I needed to have Photoshop’s “Polar Coordinates” distortion happen by code in my own app. If you have access to Photoshop you can find this option under Filters -> Distort -> “Polar Coordinates”. So thus began a quest. I figured I would just find any code example of such an effect, simply convert that into AS3 and I’d be good to go, right? Wrong. Turns out there are no rules to this effect and everyone does whatever they want. Polar Distortion is a category not a standard.

For example : This Java article seemed promising. Then I compared their shown code result against Photoshop. Who’s correct? Well it depends on what you want to achieve…

So after some further searching I found a BlitzBasic.com forum post discussing this same topic. After converting that shared code to ActionScript, I got a result similar to the original asker’s version.

This gives a result like the “Rectangular to Polar” option from Photoshop (note: The effect reversal is “Polar to Rectangular” option). Now let’s compare my AS3 code result with that of Photoshop.

As you can see my AS3 version is good, however Photoshop seems to “stretch” the pixels from the circle’s circumference towards the boundaries of the image. After some experimental math I achieved the formula as shown in the code snippet below :

  • First check which is smaller between the input image’s width or height.
  • Next should the Dist amount ever get larger than the lowest_Size then we use xB = Q; and yB = picHeight – Dist / picHeight / Math.PI;
  • Otherwise normally it would be xB = Q; and yB = R;.
    (see the full code link for the values of Q and R)
for ( y = 0; y <= picHeight ; y++) //# For each pixel of height (Y = down)
{
    for ( x = 0; x <= picWidth ; x++) //# And each width of pixels (X = across)
	{
		A = ( x - picWidth / 2 );
		B = ( y - picHeight / 2 );
		
		Dist = (Math.sqrt(A * A + B * B) * 2.0);
		
		//# check lowest size between either Image's width vs Image height
		if ( picWidth >= picHeight  ) {  lowest_SIZE = picHeight; }
		else { lowest_SIZE = picWidth; }
		
		if ( Dist >= lowest_SIZE )
		{ 
			xB = Q;
			yB = picHeight-Dist / picHeight / Math.PI;
			
			bitmapData.setPixel( x , y , Picture.getPixel( xB, yB ) );
		}
        else
        {   bitmapData.setPixel( x , y , Picture.getPixel( Q, R ) ); }
	}
}

With the above logic in place let’s check the new result :

Even trying with a different image :

Looking good. I would say the distortion is 99.5% similar to the actual Photoshop algorithm. If you zoom in, you’ll see there’s a subtle difference where it’s off by 1 or 2 degrees in the angle of distortion. That’s just a side note and is not even an actual issue. The most important thing here is cool VFX via polar distortions are now possible.

Usage examples include artistic effects as done by the excellent Sergio Albiac, or simulating camera lens blurring & chromatic aberration as explained in this interesting article. Also the first 10 seconds of this video tutorial should convince that it’s worth pursuing polar coordinates for visual effects. You can also correct image distortions like fish-eye lens, or use it for creating 360 videos similar to Youtube.

If your programming language allows running an external (Native) Process, then you could for example connect to FFmpeg and encode video in real-time by passing video frames one by one through the polar distortion code (also consider applying a distortion/warping field) to create interesting visual effects such as the “Little Planet” shown in this other article. Check out their result video on Youtube.

PS: Here is a link to the full code. It’s written in ActionScript 3.0 but the logic is easy to convert to other languages. The code only shows a function for the “Rectangular to Polar” conversion and it’s up to you, dear reader, to figure out the effect reversal if you need it (or just pay me for the solution). Also you need to implement your own smoothing filter (eg: some bi-cubic filtering) if you need to fix any jagged edges. I use this Smart Anti-Alias PixelBender shader.

Now to just pass some pixels through such distortion code and create some delicious visual effects for image or video output…

Dynamic Video Test #1

I recently found out how to send pixels (bitmap data) to the FFmpeg video tool directly from Flash using AS3 code. Thanks to this StackOverflow Answer. This encodes pixels as a video frame of a file.

One example usage is colour grading pixels through code. Below is a “first steps” video example using an AS3 method called paletteMap for making such effects. The original video can be seen at this Youtube link.



source credits : Beyonce “Single Ladies” (c) 2008 Columbia Records.
(visual effects created with Adobe Flash using ActionScript 3.0 code)


So for anything I want to be a video frame, I simply draw(); to a bitmap, pass that through my custom VFX code, and then convert the newly effected bitmap (image for frame) to bytes by using my_PixelBytes = input_BMP.bitmapData.getPixels( input_BMP.bitmapData.rect );.
When ready to convert those bytes into a video frame, simply do a process.standardInput.writeBytes ( my_PixelBytes );. For a 30 frames p/second video, the process is repeated 30 times to encode enough images (bitmap data) into a new one second’s worth of video. As simple as that. Excuse my language but that is just too badass…!! I won’t even begin to explain the why, but this capability can only be summed up in one word… KA-POW!!

The general FFmpeg setup goes like this :

//## (1) INPUT settings (settings Arguments that you send to FFmpeg)
Args_FFMPEG.push('-y'); //# overwrite (if existing filename) needed if you re-encode etc..
Args_FFMPEG.push("-f",     		"rawvideo"); 	//# input : video type (= uncompressed)
Args_FFMPEG.push("-pix_fmt", 	"argb"); 		//# input : pixel format (= uncompressed)
Args_FFMPEG.push("-s", 			"720x480"); 	//# output : picture size (width/height)
Args_FFMPEG.push("-r", 			"30"); 			//# output : frame rate (FPS)
Args_FFMPEG.push("-i", 			"-"); 			//# works same as "pipe:0"

//## (2) VIDEO settings (for output encoding type)
Args_FFMPEG.push("-c:v", 		"libx264"); 	//# output : video codec
//Args_FFMPEG.push("-profile:v", "baseline"); 	// H.264 profile (eg: high)
//Args_FFMPEG.push("-level:v", 	 "3");			// H.264 level (eg: 3.1)
Args_FFMPEG.push("-b:v", 		"2500");		//# output : video bitrate 

//## (3) AUDIO settings
Args_FFMPEG.push("-an"); //# no audio (is pixels only)

//## (4) OUTPUT settings (Gives H.264, this can later be contained in either FLV or MP4)
//## Requires TWO OUTPUT files to work. *1 is MPEG side-data(?) and *2 is actual output
Args_FFMPEG.push("tempVideoData.h264"); //# Seems needed for MPEG side-data?? (Gives blocky image)
Args_FFMPEG.push("Output.h264"); //# Gives actual output in AVC codec format

Here the output is (MPEG) H.264 which can later be contained in either MP4 or FLV formats.
Example : ffmpeg -i input.h264 -c:v copy output.mp4

link : AS3 CODE (connect to FFmpeg & encode a bitmap as video frame).

So just incase you want to try your own AS3/Flash to FFmpeg connection, I’ve put an example AS3 source code showing how to setup your Native Process code the way I did it for dynamic video encoding.
Hopefully it has helpful hints to users of other languages which can also run FFmpeg as a process (PHP / C# / JAVA / PYTHON / etc).

Video Seek using appendBytes (AS3)

Is this a world exclusive? Maybe it’s exclusive because it’s my first proper article on this blog. Today the subject matter is about searching the timeline of a video file. I cannot find a full working example with code anywhere on the internet when it comes to seeking through specific bytes of a video file when using the ActionScript 3.0 programming language. So I made my own to share. So here it is…

A quick demo from the VC:One labs showing exactly that. The shared code also even manages to step frame by frame through the video (no server tricks, just this code). A future “to-do” is to create a free API that will allow easy playback with your own app’s code and user interface design.

 

Get Adobe Flash player


 

Test with an FLV file that has MPEG (H.264) video and MP3 or AAC audio (test files provided below).

Check the code here : GitHub (AS3 code makes shown demo).

If you need some test clips:
1) Star Wars 7 trailer (FLV + H264/MP3 at 720p) – 33 MB
2) Mets Baseball video sting (FLV + H264/AAC at 480p) – 9.6 MB
3) BBC Clip “Deep Oceans” (FLV + H264/MP3 at 480p) – 14 MB

Also if demo does not work. Save and test the SWF from your desktop (not online).

To Fix:
– “Load freeze” : currently freezes if you load a file whilst another is playing. It must be paused first. Code fixing soon.
– “Step” : currently needs multiple presses (usually 4) at first before allowing user to step frame by frame.
– “Browser testing” : I can hear a subtle constant “click” via headphones (in Google’s Chrome so far) even when the video is paused etc.