qt - Blur QImage alpha channel -
i'm trying blur qimage alpha channel. current implementation use deprecated 'alphachannel' method , works slow.
qimage blurimage(const qimage & image, double radius) { qimage newimage = image.converttoformat(qimage::format_argb32); qimage alpha = newimage.alphachannel(); qimage blurredalpha = alpha; (int x = 0; x < alpha.width(); x++) { (int y = 0; y < alpha.height(); y++) { uint color = calculateaveragealpha(x, y, alpha, radius); blurredalpha.setpixel(x, y, color); } } newimage.setalphachannel(blurredalpha); return newimage; }
i trying implement using qgraphicsblureffect, doesn't affect alpha.
what proper way blur qimage alpha channel?
i have faced similar question pixel read\write access :
- invert loops. image laid out in memory succession of rows. should access first height width
- use
qimage::scanline
access data, rather expensivesqimage::pixel
,qimage::setpixel
. pixels in scan (aka row) guaranteed consecutive.
your code :
for (int ii = 0; ii < image.height(); ii++) { uchar* scan = image.scanline(ii); int depth =4; (int jj = 0; jj < image.width(); jj++) { //it in fact rgba qrgb* rgbpixel = reinterpret_cast<qrgb*>(scan + jj*depth); qcolor color(*rgbpixel); int alpha = calculateaveragealpha(ii, jj, color, image); color.setalpha(alpha); //write *rgbpixel = color.rgba(); } }
you can go further , optimize computation of alpha average. lets @ sum of pixel in radius. sum of alpha value @ (x,y) in radius s(x,y). when move 1 pixel in either direction, single line added while single line removed. lets move horizontally. if l(x,y) sum of vertical line of length 2*radius
centered around (x,y)
, have
s(x + 1, y) = s(x, y) + l(x + r + 1, y) - l(x - r, y)
which allow efficiently compute matrix of sum (then average, dividing number of pixel) in first pass.
i suspect kind of optimization implemented in better way in libraries such opencv. encourage use existing opencv functions if wish save time.
Comments
Post a Comment