简体   繁体   English

如何模糊位图(Android)?

[英]How to blur a Bitmap (Android)?

I am struggling to get Bitmaps blurred using Android. 我正在努力使用Android使位图模糊。

I have seen a lot of information about using a simple kernel like 我已经看到了很多有关使用简单内核的信息,例如

0    0    0    5    0    0    0
0    5   18   32   18    5    0
0   18   64  100   64   18    0
5   32  100  100  100   32    5
0   18   64  100   64   18    0
0    5   18   32   18    5    0
0    0    0    5    0    0    0

My problem is that I am really not sure how to multiply this with my Bitmap in an efficient way. 我的问题是我真的不确定如何以一种有效的方式将其与我的位图相乘。

Should I go through every pixel and 我应该遍历每个像素并

image.getPixel(x, y)

while storing those values to a new array (so I don't have to get those values over and over again) and then go through the array and for each value add up the surrounding values multiplied by the corresponding field in the kernel divided by 1068 (in the case of the above kernel (= all entries summed up))? 同时将这些值存储到新数组中(因此我不必一遍又一遍地获取这些值),然后遍历该数组,并为每个值加上周围的值乘以内核中的相应字段并除以1068 (在上述内核的情况下(=所有条目的总和))?

Is there any better way to do this? 有什么更好的方法吗? Is there a simple solution for the borders? 有没有简单的边界解决方案?

Or is there even something available in the Android SDK I missed? 还是我错过的Android SDK中提供了某些功能?

What you are doing is basically 2D convolution between original image I and kernel K (kernel is actually PSF - point spread function). 您要做的基本上是原始图像I和内核K之间的2D卷积(内核实际上是PSF-点扩散函数)。 If your image I is of size mxn , and kernel is of size rxs , for each point of blurred image J you need rxs multiplications, resulting in total mxnxrxs multiplications for the whole image. 如果您的图像I的大小为mxn ,内核的大小为rxs ,则对于模糊图像J的每个点,您都需要rxs乘法,从而导致整个图像的总mxnxrxs乘法。

Computationally more efficient approach would be to use DFT (Discrete Fourier Transform). 计算上更有效的方法是使用DFT(离散傅立叶变换)。 Make transforms of the image and of the kernel, and multiply them in the domain of transform, and then revert back via Inverse DFT. 对图像和内核进行变换,然后将它们在变换域中相乘,然后通过逆DFT还原。 In short: 简而言之:

J = IDFT(DFT(I)*DFT(K))

For DFT computation fast algorithms (FFT - Fast Fourier Transform) exist. 对于DFT计算,存在快速算法(FFT-快速傅立叶变换)。 You can find them in C source on the Internet. 您可以在Internet上的C源代码中找到它们。 In order to use C source, you need to use JNI (Java Native Interface), supported by the Android platform. 为了使用C源代码,您需要使用Android平台支持的JNI(Java本机接口)。

Regarding borders, when using DFT you have no issues, since blurring at the border is done circularly (eg left border values are calculated using also some right border values). 关于边界,使用DFT时没有问题,因为边界模糊是循环进行的(例如,左边界值也使用一些右边界值来计算)。

If you are working with the kernels that may be separated (2D kernel represented as outer product of 1-D kernels), then it becomes more simple. 如果您正在使用可能分离的内核(将2D内核表示为1-D内核的外部乘积),那么它将变得更加简单。 2D convolution can be represented as 1-D convolutions over rows and then over columns (or vice versa). 2D卷积可以表示为在行上然后在列上的一维卷积(反之亦然)。 The same is true for blurring using DFT. 使用DFT进行模糊处理也是如此。

Try to make use of BlurMaskFilter. 尝试使用BlurMaskFilter。

example of usage: 使用示例:

http://www.anddev.org/decorated_and_animated_seekbar_tutorial-t10937.html http://www.anddev.org/decorated_and_animated_seekbar_tutorial-t10937.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM