草庐IT

android以编程方式模糊可绘制的imageview

coder 2023-11-21 原文

我想在 Android 中以编程方式模糊和取消模糊图像。

我听说在 API 14 之后不再支持 android 标志“blur”,但我还是想使用 Java 方法。我的主要问题是从 Imageview 可绘制对象中操作位图。

我如何从 ImageView 获取位图并对其进行操作(可能会使用高斯模糊)并将其设置回 ImageView ?我认为这个过程包括提取可绘制对象,将可绘制对象转换为位图,在该位图上执行我的模糊方法,然后执行相反的操作,直到再次将其设置为 ImageView

但是我想把这个过程说清楚,谢谢

最佳答案

以下是实现高斯模糊的代码。希望这可以帮助你

import android.graphics.Bitmap;
import android.graphics.Matrix;

/**
 * @author robert.hinds
 *
 * Wrapper class for the Android Bitmap - used by all filters
 *
 */
public class AndroidImage {

    //original bitmap image
    private Bitmap image;

    //format of image (jpg/png)
    private String formatName;

    //dimensions of image
    private int width, height;

    // RGB Array Color
    protected int[] colourArray;

    public AndroidImage(Bitmap img){        
        this.image =  img;
        formatName = "jpg";
        width = img.getWidth();
        height = img.getHeight();
        updateColourArray();
    }


    /**
     * Method to reset the image to a solid colour
     * 
     * @param color - colour to rest the entire image to
     */
    public void clearImage(int color){
        for(int y=0; y<height; y++){
            for(int x=0; x<width; x++){
                image.setPixel(x, y, color);
            }
        }
    }


    /**
     * Set colour array for image - called on initialisation
     * by constructor
     * 
     * @param bitmap
     */
    private void updateColourArray(){
        colourArray = new int[width * height];
        image.getPixels(colourArray, 0, width, 0, 0, width, height);
        int r, g, b;
        for (int y = 0; y < height; y++){
            for (int x = 0; x < width; x++){
                int index = y * width + x;
                r = (colourArray[index] >> 16) & 0xff;
                g = (colourArray[index] >> 8) & 0xff;
                b = colourArray[index] & 0xff;
                colourArray[index] = 0xff000000 | (r << 16) | (g << 8) | b;
            }
        }
    }


    /**
     * Method to set the colour of a specific pixel
     * 
     * @param x
     * @param y
     * @param colour
     */
    public void setPixelColour(int x, int y, int colour){
        colourArray[((y*image.getWidth()+x))] = colour;
        image.setPixel(x, y, colour);
    }

    /**
     * Get the colour for a specified pixel
     * 
     * @param x
     * @param y
     * @return colour
     */
    public int getPixelColour(int x, int y){
        return colourArray[y*width+x];
    }

    /**
     * Set the colour of a specified pixel from an RGB combo
     * 
     * @param x
     * @param y
     * @param c0
     * @param c1
     * @param c2
     */
    public void setPixelColour(int x, int y, int c0, int c1, int c2){
        colourArray[((y*image.getWidth()+x))] = (255 << 24) + (c0 << 16) + (c1 << 8) + c2;
        image.setPixel(x, y, colourArray[((y*image.getWidth()+x))]);
    }

    /**
     * Method to get the RED colour for the specified 
     * pixel 
     * @param x
     * @param y
     * @return colour of R
     */
    public int getRComponent(int x, int y){
        return (getColourArray()[((y*width+x))]& 0x00FF0000) >>> 16;
    }


    /**
     * Method to get the GREEN colour for the specified 
     * pixel 
     * @param x
     * @param y
     * @return colour of G
     */
    public int getGComponent(int x, int y){
        return (getColourArray()[((y*width+x))]& 0x0000FF00) >>> 8;
    }


    /**
     * Method to get the BLUE colour for the specified 
     * pixel 
     * @param x
     * @param y
     * @return colour of B
     */
    public int getBComponent(int x, int y){
        return (getColourArray()[((y*width+x))] & 0x000000FF);
    }



    /**
     * Method to rotate an image by the specified number of degrees
     * 
     * @param rotateDegrees
     */
    public void rotate (int rotateDegrees){
        Matrix mtx = new Matrix();
        mtx.postRotate(rotateDegrees);
        image = Bitmap.createBitmap(image, 0, 0, width, height, mtx, true);
        width = image.getWidth();
        height = image.getHeight();
        updateColourArray();
    }


    /**
     * @return the image
     */
    public Bitmap getImage() {
        return image;
    }


    /**
     * @param image the image to set
     */
    public void setImage(Bitmap image) {
        this.image = image;
    }


    /**
     * @return the formatName
     */
    public String getFormatName() {
        return formatName;
    }


    /**
     * @param formatName the formatName to set
     */
    public void setFormatName(String formatName) {
        this.formatName = formatName;
    }


    /**
     * @return the width
     */
    public int getWidth() {
        return width;
    }


    /**
     * @param width the width to set
     */
    public void setWidth(int width) {
        this.width = width;
    }


    /**
     * @return the height
     */
    public int getHeight() {
        return height;
    }


    /**
     * @param height the height to set
     */
    public void setHeight(int height) {
        this.height = height;
    }


    /**
     * @return the colourArray
     */
    public int[] getColourArray() {
        return colourArray;
    }


    /**
     * @param colourArray the colourArray to set
     */
    public void setColourArray(int[] colourArray) {
        this.colourArray = colourArray;
    }

}

import com.bvise.fotoflipper.core.AndroidImage;




public interface IAndroidFilter {

    public AndroidImage process(AndroidImage imageIn);
}


import android.graphics.Bitmap;
import android.graphics.Color;

public class ConvolutionMatrix
{
    public static final int SIZE = 3;

    public double[][] Matrix;
    public double Factor = 1;
    public double Offset = 1;

    public ConvolutionMatrix(int size) {
        Matrix = new double[size][size];
    }

    public void setAll(double value) {
        for (int x = 0; x < SIZE; ++x) {
            for (int y = 0; y < SIZE; ++y) {
                Matrix[x][y] = value;
            }
        }
    }

    public void applyConfig(double[][] config) {
        for(int x = 0; x < SIZE; ++x) {
            for(int y = 0; y < SIZE; ++y) {
                Matrix[x][y] = config[x][y];
            }
        }
    }

    public static Bitmap computeConvolution3x3(Bitmap src, ConvolutionMatrix matrix) {
        int width = src.getWidth();
        int height = src.getHeight();
        Bitmap result = Bitmap.createBitmap(width, height, src.getConfig());

        int A, R, G, B;
        int sumR, sumG, sumB;
        int[][] pixels = new int[SIZE][SIZE];

        for(int y = 0; y < height - 2; ++y) {
            for(int x = 0; x < width - 2; ++x) {

                // get pixel matrix
                for(int i = 0; i < SIZE; ++i) {
                    for(int j = 0; j < SIZE; ++j) {
                        pixels[i][j] = src.getPixel(x + i, y + j);
                    }
                }

                // get alpha of center pixel
                A = Color.alpha(pixels[1][1]);

                // init color sum
                sumR = sumG = sumB = 0;

                // get sum of RGB on matrix
                for(int i = 0; i < SIZE; ++i) {
                    for(int j = 0; j < SIZE; ++j) {
                        sumR += (Color.red(pixels[i][j]) * matrix.Matrix[i][j]);
                        sumG += (Color.green(pixels[i][j]) * matrix.Matrix[i][j]);
                        sumB += (Color.blue(pixels[i][j]) * matrix.Matrix[i][j]);
                    }
                }

                // get final Red
                R = (int)(sumR / matrix.Factor + matrix.Offset);
                if(R < 0) { R = 0; }
                else if(R > 255) { R = 255; }

                // get final Green
                G = (int)(sumG / matrix.Factor + matrix.Offset);
                if(G < 0) { G = 0; }
                else if(G > 255) { G = 255; }

                // get final Blue
                B = (int)(sumB / matrix.Factor + matrix.Offset);
                if(B < 0) { B = 0; }
                else if(B > 255) { B = 255; }

                // apply new pixel
                result.setPixel(x + 1, y + 1, Color.argb(A, R, G, B));
            }
        }

        // final image
        return result;
    }
}

import android.graphics.Bitmap;

import com.bvise.fotoflipper.core.AndroidImage;
import com.bvise.fotoflipper.core.ConvolutionMatrix;
import com.bvise.fotoflipper.filters.IAndroidFilter;

public class GaussianBlur implements IAndroidFilter{

    @Override
    public AndroidImage process(AndroidImage imageIn) {
        // TODO Auto-generated method stub
        Bitmap src=imageIn.getImage();
        double[][] GaussianBlurConfig = new double[][] {
                { 1, 2, 1 },
                { 2, 4, 2 },
                { 1, 2, 1 }
            };
            ConvolutionMatrix convMatrix = new ConvolutionMatrix(3);
            convMatrix.applyConfig(GaussianBlurConfig);
            convMatrix.Factor = 200;
            convMatrix.Offset = 0;
            return new AndroidImage(ConvolutionMatrix.computeConvolution3x3(src, convMatrix));
    }


}

关于android以编程方式模糊可绘制的imageview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14555937/

有关android以编程方式模糊可绘制的imageview的更多相关文章

  1. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby-on-rails - 正确的 Rails 2.1 做事方式 - 2

    question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参

  4. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  5. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  6. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

  7. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  8. ruby - 鸭子输入字符串、符号和数组的优雅方式? - 2

    这是针对我无法破坏的现有公共(public)API,但我确实希望对其进行扩展。目前,该方法采用字符串或符号或任何其他在作为第一个参数传递给send时有意义的内容我想添加发送字符串、符号等列表的功能。我可以只使用is_a吗?数组,但还有其他发送列表的方法,这不是很像ruby​​。我将调用列表中的map,所以第一个倾向是使用respond_to?:map。但是字符串也会响应:map,所以这行不通。 最佳答案 如何将它们全部视为数组?String的行为与仅包含String的Array相同:deffoo(obj,arg)[*arg].eac

  9. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  10. ruby - 如何以编程方式删除实例上的 "singleton information"以使其编码(marshal)? - 2

    我创建了一个由于“在运行时执行的单例元类定义”而无法编码的对象(这段代码的描述是否正确?)。这是通过以下代码执行的:#defineclassXthatmyusesingletonclassmetaprogrammingfeatures#throughcallofmethod:break_marshalling!classXdefbreak_marshalling!meta_class=class我该怎么做才能使对象编码正确?是否可以从对象instance_of_x的classX中“移除”单例组件?我真的需要一个建议,因为我们的一些对象需要通过Marshal.dump序列化机制进行缓存。

随机推荐