canvas实现高斯模糊

对于模糊图片这个效果的实现,其实css3中的filter属性也能够实现,但是这个属性的兼容性不是很好,所以我们通常不用这种方法实现,而使用canvas配合JS实现。

高斯模糊

就是按照高斯曲线对图片进行模糊处理,所谓”模糊”,可以理解成每个像素都取周边像素的平均值,这样的话就会是图片像素值处于一种“平滑化”,产生模糊的效果。

局部模糊效果图

这里写图片描述

gauss.js代码

function gaussBlur(imgData) {
    var pixes = imgData.data;
    var width = imgData.width;
    var height = imgData.height;
    var gaussMatrix = [],
        gaussSum = 0,
        x, y,
        r, g, b, a,
        i, j, k, len;

    var radius = 10;
    var sigma = 5;

    a = 1 / (Math.sqrt(2 * Math.PI) * sigma);
    b = -1 / (2 * sigma * sigma);
    //生成高斯矩阵
    for (i = 0, x = -radius; x <= radius; x++, i++){
        g = a * Math.exp(b * x * x);
        gaussMatrix[i] = g;
        gaussSum += g;

    }
    //归一化, 保证高斯矩阵的值在[0,1]之间
    for (i = 0, len = gaussMatrix.length; i < len; i++) {
        gaussMatrix[i] /= gaussSum;
    }
    //x 方向一维高斯运算
    for (y = 0; y < height; y++) {
        for (x = 0; x < width; x++) {
            r = g = b = a = 0;
            gaussSum = 0;
            for(j = -radius; j <= radius; j++){
                k = x + j;
                if(k >= 0 && k < width){//确保 k 没超出 x 的范围
                    //r,g,b,a 四个一组
                    i = (y * width + k) * 4;
                    r += pixes[i] * gaussMatrix[j + radius];
                    g += pixes[i + 1] * gaussMatrix[j + radius];
                    b += pixes[i + 2] * gaussMatrix[j + radius];
                    // a += pixes[i + 3] * gaussMatrix[j];
                    gaussSum += gaussMatrix[j + radius];
                }
            }
            i = (y * width + x) * 4;
            // 除以 gaussSum 是为了消除处于边缘的像素, 高斯运算不足的问题
            // console.log(gaussSum)
            pixes[i] = r / gaussSum;
            pixes[i + 1] = g / gaussSum;
            pixes[i + 2] = b / gaussSum;
            // pixes[i + 3] = a ;
        }
    }
    //y 方向一维高斯运算
    for (x = 0; x < width; x++) {
        for (y = 0; y < height; y++) {
            r = g = b = a = 0;
            gaussSum = 0;
            for(j = -radius; j <= radius; j++){
                k = y + j;
                if(k >= 0 && k < height){//确保 k 没超出 y 的范围
                    i = (k * width + x) * 4;
                    r += pixes[i] * gaussMatrix[j + radius];
                    g += pixes[i + 1] * gaussMatrix[j + radius];
                    b += pixes[i + 2] * gaussMatrix[j + radius];
                    // a += pixes[i + 3] * gaussMatrix[j];
                    gaussSum += gaussMatrix[j + radius];
                }
            }
            i = (y * width + x) * 4;
            pixes[i] = r / gaussSum;
            pixes[i + 1] = g / gaussSum;
            pixes[i + 2] = b / gaussSum;
        }
    }
    return imgData;
}

index.html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        canvas {
            border: 1px solid black;
        }
        img {
            display: none;
        }
    </style>
</head>
<body>
    <img src="1.jpg" id="img">
    <canvas width="450" height="300" id="canvas"></canvas>
    <script src="gauss.js"></script>
    <script>
        var img = document.getElementById('img');
        var canvas = document.getElementById('canvas');
        var ctx = canvas.getContext('2d');
        img.onload = function () {
            ctx.drawImage(img, 0, 0, 450, 300);
            var data = ctx.getImageData(225, 0, 450, 300);
            var emptyData = ctx.createImageData(225, 300);
            emptyData = gaussBlur(data);
            ctx.putImageData(emptyData, 225, 0);
        }
    </script>
</body>
</html>
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现 AlertDialog 高斯模糊的方法与一般的 View 高斯模糊基本相同,只需要在 AlertDialog 的背景中添加高斯模糊效果即可。下面是使用 RenderScript 实现 AlertDialog 高斯模糊的示例代码: 1. 在 res/values/styles.xml 文件中定义一个 MyAlertDialogTheme 主题,用于设置 AlertDialog 的样式: ``` <style name="MyAlertDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert"> <item name="android:windowBackground">@drawable/dialog_bg_blur</item> </style> ``` 2. 在 res/drawable 文件夹中创建一个 dialog_bg_blur.xml 文件,用于设置 AlertDialog 背景: ``` <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 设置底层背景 --> <item android:id="@android:id/background"> <shape android:shape="rectangle"> <solid android:color="@android:color/transparent" /> </shape> </item> <!-- 设置高斯模糊层 --> <item android:id="@+id/dialog_blur_layer"> <bitmap android:src="@drawable/dialog_bg" /> </item> </layer-list> ``` 其中,dialog_bg.xml 是一个不带高斯模糊效果的背景图片。 3. 在 res/drawable-v21 文件夹中创建一个 dialog_bg_blur.xml 文件,用于设置 AlertDialog 背景(仅适用于 Android 5.0 及以上版本): ``` <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 设置底层背景 --> <item android:id="@android:id/background"> <shape android:shape="rectangle"> <solid android:color="@android:color/transparent" /> </shape> </item> <!-- 设置高斯模糊层 --> <item android:id="@+id/dialog_blur_layer"> <bitmap android:src="@drawable/dialog_bg" /> <blur android:radius="25dp" android:scale="1" /> </item> </layer-list> ``` 其中,blur 标签用于设置高斯模糊效果,radius 属性表示模糊半径,scale 属性表示模糊程度。 4. 在 Java 代码中创建一个 Bitmap 对象,用于存储高斯模糊后的图片: ``` private Bitmap getBlurBitmap(Context context, Bitmap bitmap) { // 创建一个空的 Bitmap 对象 Bitmap blurBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); // 创建一个 RenderScript 对象 RenderScript rs = RenderScript.create(context); // 创建一个 Allocation 对象,用于存储原始图片数据 Allocation input = Allocation.createFromBitmap(rs, bitmap); // 创建一个 Allocation 对象,用于存储高斯模糊后的图片数据 Allocation output = Allocation.createFromBitmap(rs, blurBitmap); // 创建一个 ScriptIntrinsicBlur 对象,用于实现高斯模糊效果 ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); // 设置高斯模糊半径 script.setRadius(25); // 执行高斯模糊 script.setInput(input); script.forEach(output); // 将高斯模糊后的图片数据保存到 Bitmap 对象中 output.copyTo(blurBitmap); // 销毁 RenderScript 对象 rs.destroy(); return blurBitmap; } ``` 5. 在 Java 代码中创建一个 AlertDialog 对象,并为其设置 MyAlertDialogTheme 主题: ``` AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.MyAlertDialogTheme); builder.setTitle("AlertDialog"); builder.setMessage("This is an AlertDialog with blur background."); builder.setPositiveButton("OK", null); builder.setNegativeButton("Cancel", null); AlertDialog dialog = builder.create(); ``` 6. 在 Java 代码中获取 dialog_blur_layer 图层,并为其设置高斯模糊后的 Bitmap 对象: ``` // 获取 dialog_blur_layer 图层 ViewGroup decorView = (ViewGroup) dialog.getWindow().getDecorView(); ViewGroup contentContainer = (ViewGroup) decorView.findViewById(android.R.id.content); FrameLayout container = (FrameLayout) contentContainer.getChildAt(0); ImageView blurLayer = (ImageView) container.findViewById(R.id.dialog_blur_layer); // 获取原始图片 Drawable drawable = blurLayer.getDrawable(); Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); // 获取高斯模糊后的图片 Bitmap blurBitmap = getBlurBitmap(this, bitmap); // 将高斯模糊后的图片设置给 dialog_blur_layer 图层 blurLayer.setImageBitmap(blurBitmap); ``` 需要注意的是,Android 中的 RenderScript 只能在 Android 4.2(API 17)及以上版本中使用。在使用 RenderScript 时,需要注意内存的使用和回收,以避免内存泄漏和程序崩溃。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值