August 25th, 2009 |
Published in
Uncategorized | 14 Comments
There is bilinear resampling by Pixel Bender already, why not bicubic too?
With the very helpful Java implementation, I can get bicubic resampling running in Pixel Bender in hours.
Here is my result, along with the resampling results in PhotoShop as a comparison:
 Source image (size 4x4, scaled by your browser)
 Source image enlarged by PS (nearest neighbor)
 Bicubic resampling by Pixel Bender |
There is some difference with PhotoShop’s versions (below), hope it’s not my mistake…
 Bicubic resampling by PhotoShop.
 Bicubic smoother by PhotoShop
 Bicubic sharper by PhotoShop |
My codes can be downloaded below:
Bicubic resampling sample program source (with PB source)
Update:
Notified by author of the Java version, the Java code was wrong and has been updated. Here below is my updated code:
Bicubic resampling sample program source (with PB source)

updated output of PB
Update (2010-11-17):
Once again notified by Paul, the author of the Java version, there is something need to be updated. Here below is my updated code:
Bicubic resampling sample program source (with PB source)

updated output of PB
There is bilinear resampling by Pixel Bender already, why not bicubic too?
With the very helpful Java implementation, I can get bicubic resampling running in Pixel Bender in hours.
Here is my result, along with the resampling results in PhotoShop as a comparison:
[caption id="attachment_506" align="alignleft" width="200" caption="Source image (size 4x4, scaled by your browser)"][/caption]
[caption id="attachment_507" align="alignleft" width="200" caption="Source image enlarged by PS (nearest neighbor)"][/caption]
[caption id="attachment_508" align="alignleft" width="200" caption="Bicubic resampling by Pixel Bender"][/caption]
There is some difference with PhotoShop's versions (below), hope it's not my mistake...
[caption id="attachment_509" align="alignleft" width="200" caption="Bicubic resampling by PhotoShop."][/caption]
[caption id="attachment_510" align="alignleft" width="200" caption="Bicubic smoother by PhotoShop"][/caption]
[caption id="attachment_511" align="alignleft" width="200" caption="Bicubic sharper by PhotoShop"][/caption]
My codes can be downloaded below:
Bicubic resampling sample program source (with PB source)
Update:
Notified by author of the Java version, the Java code was wrong and has been updated. Here below is my updated code:
Bicubic resampling sample program source (with PB source)
[caption id="attachment_724" align="alignnone" width="200" caption="updated output of PB"][/caption]
Update (2010-11-17):
Once again notified by Paul, the author of the Java version, there is something need to be updated. Here below is my updated code:
Bicubic resampling sample program source (with PB source)
[caption id="attachment_724" align="alignleft" width="200" caption="updated output of PB"][/caption]
November 24th, 2009 at 9:13 am (#)
This filter looks fantastic when upsampling an image, but it is really jagged when downsampling. Any thoughts?
November 24th, 2009 at 10:00 pm (#)
The code I ported from is actually designed for up sampling only as the name bicubic interpolation suggests. It is because it takes the nearest four points to calculate the values in between.
More pixels (>4) are needed for “correct” calculation in high ratio down sampling.
January 15th, 2010 at 5:38 pm (#)
[...] BitmapData, Bitmap, ByteArray, read this article. Continue reading about bilinear resampling and bicubic resampling using pixel [...]
January 16th, 2010 at 10:40 pm (#)
Hi, I have just figured out smoother downscaling
http://blog.yoz.sk/2010/01/how-to-resize-an-image-with-actionscript/
February 26th, 2010 at 5:20 am (#)
Hi, I wrote the Java implementation and made a mistake: the code didn’t do bicubic interpolation, sorry.
I fixed it a few days ago. So this code for Pixel Blender is wrong too and also has to be fixed.
March 1st, 2010 at 2:55 am (#)
@Paul Breeuwsma Thanks for the info! I’ve just updated the code according to your changes.
June 21st, 2010 at 8:47 am (#)
Hi, I changed my code again, already a while ago, the new formula is more smooth than the one used here now. But now, it should be perfect.
August 19th, 2010 at 5:54 am (#)
Thanks for the code Andy. When scaling a bitmap of size 700×458 by 8, the kernal took about 2.1 seconds. Taking a look at the pb code, pre-computing some reoccurring float operations gave some very promising performance improvements. After the mod, I am seeing the same shaderJob taking 1.2 seconds.
Here is the code:
kernel bicubicResampling
{
parameter float2 scale
;
input image4 src;
output pixel4 dst;
void
evaluatePixel()
{
float2 scaledPt = outCoord() * scale – float2(0.5,0.5);
float2 pt = floor(scaledPt);
//http://www.paulinternet.nl/?page=bicubic
float4 p00 = sampleNearest(src,pt+float2(-1.0,-1.0));
float4 p01 = sampleNearest(src,pt+float2(-1.0,0.0));
float4 p02 = sampleNearest(src,pt+float2(-1.0,1.0));
float4 p03 = sampleNearest(src,pt+float2(-1.0,2.0));
float4 p10 = sampleNearest(src,pt+float2(0.0,-1.0));
float4 p11 = sampleNearest(src,pt+float2(0.0,0.0));
float4 p12 = sampleNearest(src,pt+float2(0.0,1.0));
float4 p13 = sampleNearest(src,pt+float2(0.0,2.0));
float4 p20 = sampleNearest(src,pt+float2(1.0,-1.0));
float4 p21 = sampleNearest(src,pt+float2(1.0,0.0));
float4 p22 = sampleNearest(src,pt+float2(1.0,1.0));
float4 p23 = sampleNearest(src,pt+float2(1.0,2.0));
float4 p30 = sampleNearest(src,pt+float2(2.0,-1.0));
float4 p31 = sampleNearest(src,pt+float2(2.0,0.0));
float4 p32 = sampleNearest(src,pt+float2(2.0,1.0));
float4 p33 = sampleNearest(src,pt+float2(2.0,2.0));
//pre-computes
float4 t2p01 = 2.0*p01;
float4 t2p02 = 2.0*p02;
float4 t2p03 = 2.0*p03;
float4 t2p10 = 2.0*p10;
float4 t2p11 = 2.0*p11;
float4 t2p12 = 2.0*p12;
float4 t2p13 = 2.0*p13;
float4 t2p20 = 2.0*p20;
float4 t2p21 = 2.0*p21;
float4 t2p30 = 2.0*p30;
float4 t2p31 = 2.0*p31;
float4 t4p10 = 4.0*p10;
float4 t4p11 = 4.0*p11;
float4 t4p01 = 4.0*p01;
float4 t4p00 = 4.0*p00;
float4 n2p00 = -2.0*p00;
float4 p10mp12 = -p10 + p12;
float4 p00mp01 = p00 – p01;
float4 p32ap33 = p32 – p33;
float4 p22ap23 = p22 – p23;
float4 p00mp02 = p00 – p02;
float4 p02mp03 = p02 – p03;
float4 p12ap13 = p12 – p13;
float4 p02mmp03 = p02 – p03;
float4 np10ap11 = -p10 + p11;
float4 a02 = t2p10 – t2p11 + p12ap13;
float4 a03 = np10ap11 – p12ap13;
float4 a11 = p00mp02 – p20 + p22;
float4 a12 = n2p00 + t2p01 – p02mp03 + t2p20 – t2p21 + p22ap23;
float4 a13 = p00mp01 + p02mmp03 – p20 + p21 – p22ap23;
float4 a20 = t2p01 – t2p11 + p21 – p31;
float4 a21 = n2p00 + t2p02 + t2p10 – t2p12 – p20 + p22 + p30 – p32;
float4 a22 = t4p00 – t4p01 + t2p02 – t2p03 – t4p10 + t4p11 – t2p12 + t2p13 + t2p20 – t2p21 + p22ap23 – t2p30 + t2p31 – p32ap33;
float4 a23 = n2p00 + t2p01 – t2p02 + t2p03 + t2p10 – t2p11 + t2p12 – t2p13 – p20 + p21 – p22 + p23 + p30 – p31 + p32ap33;
float4 a30 = -p01 + p11 – p21 + p31;
float4 a31 = p00mp02 – p10 + p12 + p20 – p22 – p30 + p32;
float4 a32 = n2p00 + t2p01 – p02mp03 + t2p10 – t2p11 + p12 – p13 – t2p20 + t2p21 – p22ap23 + t2p30 – t2p31 + p32ap33;
float4 a33 = p00mp01 + p02mmp03 + np10ap11 – p12ap13 + p20 – p21 + p22 – p23 – p30 + p31 – p32ap33;
float x = scaledPt.x – pt.x;
float x2 = x * x;
float x3 = x2 * x;
float y = scaledPt.y – pt.y;
float y2 = y * y;
float y3 = y2 * y;
dst = p11 + p10mp12 * y + a02 * y2 + a03 * y3 +
(-p01 + p21) * x + a11 * x * y + a12 * x * y2 + a13 * x * y3 +
a20 * x2 + a21 * x2 * y + a22 * x2 * y2 + a23 * x2 * y3 +
a30 * x3 + a31 * x3 * y + a32 * x3 * y2 + a33 * x3 * y3;
}
}
August 19th, 2010 at 9:33 pm (#)
[...] http://blog.onthewings.net/2009/08/25/bicubic-resampling-by-pixel-bender/ window.fbAsyncInit = function() { FB.init({appId: "", status: true, cookie: true, xfbml: true}); }; (function() { var e = document.createElement("script"); e.async = true; e.src = document.location.protocol + "//connect.facebook.net/en_US/all.js"; document.getElementById("fb-root").appendChild(e); }()); [Translate] Share! 관련된 글:색상혼합과 픽셀벤더를 이용한 가상 디스플레이 계층 [...]
November 17th, 2010 at 2:35 am (#)
@Paul
Thanks for the info and the works! I’ve updated it again.
@Josh
Great to see the performance gain!
However, as the code is changed according to Paul, your optimization need to be updated too.
I haven’t incorporated your optimization since I do not have the time to do so. Feel free to share with us your optimized version again
April 3rd, 2011 at 11:36 pm (#)
Hello Andy,
What about video upscaling; does flash player is default to low quality nearest neighbor when dealing with video? and if so is your code applicable to video upscaling?
It is a pity that Adobe do not implement such highly required feature natively in flash player and we still need custom coding to achieve desired resampling method.
April 4th, 2011 at 3:57 pm (#)
@Soroush
I’m not sure about video upscaling, but I believe it is linear. For latest version of FP, if there is hardware decoding, the scaling should be done by graphic card too.
The bicubic pb filter can be applied to video, but it probably will consume lots of CPU power.
April 12th, 2011 at 11:56 pm (#)
[...] http://blog.onthewings.net/2009/08/25/bicubic-resampling-by-pixel-bender/ [...]
December 26th, 2011 at 4:11 pm (#)
hi
thanks for sharing
is there any code sample
thanks