精华内容
下载资源
问答
  • Android 圆形头像两种实现方式

    万次阅读 2018-03-22 19:30:12
    圆形头像在实际开发中实际很常见,一般来说,主要有两种实现方式: 第一种: 使用 Paint 的 Xfermode 实战 第二种方法: 使用 BitmapShader 实现 第一种: 使用 Paint 的 Xfermode 实战 圆形头像...

    Android 圆形头像的两种实现方式

    前言

    这篇博客只是为了做一个记录而已,方便而后查询,核心代码都是直接采用鸿洋博客里面的代码的。


    圆形头像在实际开发中实际很常见,一般来说,主要有两种实现方式:

    • 第一种: 使用 Paint 的 Xfermode 实战
    • 第二种方法: 使用 BitmapShader 实现

    第一种: 使用 Paint 的 Xfermode 实战

    image

    圆形头像,我们可以看成是 在原图上面绘制一个圆,再取交集。

    从代码的角度来讲,先绘制 Dst,再绘制 Src,显示的区域是二者交集,由此可知 SrcIn 符合我们的要求。

    圆形图片的核心思路

    • 取出 Bitmap,并根据图片的宽高计算缩放比例
    • 设置 Paint 的 setXfermode
    • 在 onDraw 方法里面绘制 Bitmap

    核心代码

      protected void onDraw(Canvas canvas)  
        {  
            //在缓存中取出bitmap  
            Bitmap bitmap = mWeakBitmap == null ? null : mWeakBitmap.get();  
      
            if (null == bitmap || bitmap.isRecycled())  
            {  
                //拿到Drawable  
                Drawable drawable = getDrawable();  
                //获取drawable的宽和高  
                int dWidth = drawable.getIntrinsicWidth();  
                int dHeight = drawable.getIntrinsicHeight();  
      
                if (drawable != null)  
                {  
                    //创建bitmap  
                    bitmap = Bitmap.createBitmap(getWidth(), getHeight(),  
                            Config.ARGB_8888);  
                    float scale = 1.0f;  
                    //创建画布  
                    Canvas drawCanvas = new Canvas(bitmap);  
                    //按照bitmap的宽高,以及view的宽高,计算缩放比例;因为设置的src宽高比例可能和imageview的宽高比例不同,这里我们不希望图片失真;  
                    if (type == TYPE_ROUND)  
                    {  
                        // 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值;  
                        scale = Math.max(getWidth() * 1.0f / dWidth, getHeight()  
                                * 1.0f / dHeight);  
                    } else  
                    {  
                        scale = getWidth() * 1.0F / Math.min(dWidth, dHeight);  
                    }  
                    //根据缩放比例,设置bounds,相当于缩放图片了  
                    drawable.setBounds(0, 0, (int) (scale * dWidth),  
                            (int) (scale * dHeight));  
                    drawable.draw(drawCanvas);  
                    if (mMaskBitmap == null || mMaskBitmap.isRecycled())  
                    {  
                        mMaskBitmap = getBitmap();  
                    }  
                    // Draw Bitmap.  
                    mPaint.reset();  
                    mPaint.setFilterBitmap(false);  
                    mPaint.setXfermode(mXfermode);  
                    //绘制形状  
                    drawCanvas.drawBitmap(mMaskBitmap, 0, 0, mPaint);  
                    mPaint.setXfermode(null);  
                    //将准备好的bitmap绘制出来  
                    canvas.drawBitmap(bitmap, 0, 0, null);  
                    //bitmap缓存起来,避免每次调用onDraw,分配内存  
                    mWeakBitmap = new WeakReference<Bitmap>(bitmap);  
                }  
            }  
            //如果bitmap还存在,则直接绘制即可  
            if (bitmap != null)  
            {  
                mPaint.setXfermode(null);  
                canvas.drawBitmap(bitmap, 0.0f, 0.0f, mPaint);  
                return;  
            }  
      
        }  
        /** 
         * 绘制形状 
         * @return 
         */  
        public Bitmap getBitmap()  
        {  
            Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(),  
                    Bitmap.Config.ARGB_8888);  
            Canvas canvas = new Canvas(bitmap);  
            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);  
            paint.setColor(Color.BLACK);  
      
            if (type == TYPE_ROUND)  
            {  
                canvas.drawRoundRect(new RectF(0, 0, getWidth(), getHeight()),  
                        mBorderRadius, mBorderRadius, paint);  
            } else  
            {  
                canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2,  
                        paint);  
            }  
      
            return bitmap;  
        }  
    

    以上代码来自鸿洋大神的博客 Android Xfermode 实战实现圆形、圆角图片


    第二种方法: 使用 BitmapShader 实现

    Shader used to draw a bitmap as a texture.

    官方文档说的很清楚了:BitmapShader的作用是使用特定的图片来作为纹理来使用。

    BitmapShader 的构造函数

    public BitmapShader(@NonNull Bitmap bitmap, TileMode tileX, TileMode tileY)
    

    三个参数:

    • bitmap 指的是要作为纹理的图片,
    • tileX 指的是在x方向纹理的绘制模式,
    • tileY 指的是Y方向上的绘制模式。

    TileMode 源码:

    public enum TileMode {
            /**
             * replicate the edge color if the shader draws outside of its
             * original bounds
             */
            CLAMP   (0),
            /**
             * repeat the shader's image horizontally and vertically
             */
            REPEAT  (1),
            /**
             * repeat the shader's image horizontally and vertically, alternating
             * mirror images so that adjacent images always seam
             */
            MIRROR  (2);
        
            TileMode(int nativeInt) {
                this.nativeInt = nativeInt;
            }
            final int nativeInt;
        }
    

    TileMode 是一个枚举类型,有3个可能的值:

    • CLMP 如果需要填充的内容大小超过了bitmap size 就选bitmap 边界的颜色进行扩展
    • REPEAT重复,不断的重复bitmap去填满,如果绘制的区域大于纹理图片的话,纹理图片会在这片区域不断重复
    • MIRROR镜像的去填满。如果绘制的区域大于纹理图片的话,纹理图片会以镜像的形式重复出现

    BitmapShader 实战 实现圆形、圆角图片 核心思路

    • 取出 bitmap
    • 用 BitmapShader 去装饰 bitmap,并设置给画笔
    • 在 onDraw 方法中,调用 canvas 的 draw 方法绘制

    伪代码实现思路

    //创建
    BitmapShader shader=new BitmapShader(bitmap,TileMode.CLAMP,TileMode.CLAMP);
    Paint paint=new Paint();
    //为paint 设置 Shader
    paint.setShader(shader);
    //这样就可以使用shader的纹理去覆盖绘制的图形的表面了,其中根据:CLAMP,REPEAT,MIRROR,
    //来确定纹理的绘制模式
    canvas.draw**(***,paint);
    

    核心代码实心思路

    @Override  
        protected void onDraw(Canvas canvas)  
        {  
            if (getDrawable() == null)  
            {  
                return;  
            }  
            setUpShader();  
      
            if (type == TYPE_ROUND)  
            {  
                canvas.drawRoundRect(mRoundRect, mBorderRadius, mBorderRadius,  
                        mBitmapPaint);  
            } else  
            {  
                canvas.drawCircle(mRadius, mRadius, mRadius, mBitmapPaint);  
                // drawSomeThing(canvas);  
            }  
        }  
          
        @Override  
        protected void onSizeChanged(int w, int h, int oldw, int oldh)  
        {  
            super.onSizeChanged(w, h, oldw, oldh);  
            // 圆角图片的范围  
            if (type == TYPE_ROUND)  
                mRoundRect = new RectF(0, 0, getWidth(), getHeight());  
        }  
        
        
        /** 
         * 初始化BitmapShader 
         */  
        private void setUpShader()  
        {  
            Drawable drawable = getDrawable();  
            if (drawable == null)  
            {  
                return;  
            }  
      
            Bitmap bmp = drawableToBitamp(drawable);  
            // 将bmp作为着色器,就是在指定区域内绘制bmp  
            mBitmapShader = new BitmapShader(bmp, TileMode.CLAMP, TileMode.CLAMP);  
            float scale = 1.0f;  
            if (type == TYPE_CIRCLE)  
            {  
                // 拿到bitmap宽或高的小值  
                int bSize = Math.min(bmp.getWidth(), bmp.getHeight());  
                scale = mWidth * 1.0f / bSize;  
      
            } else if (type == TYPE_ROUND)  
            {  
                // 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值;  
                scale = Math.max(getWidth() * 1.0f / bmp.getWidth(), getHeight()  
                        * 1.0f / bmp.getHeight());  
            }  
            // shader的变换矩阵,我们这里主要用于放大或者缩小  
            mMatrix.setScale(scale, scale);  
            // 设置变换矩阵  
            mBitmapShader.setLocalMatrix(mMatrix);  
            // 设置shader  
            mBitmapPaint.setShader(mBitmapShader);  
        }  
    

    以上代码来自鸿洋大神的 Android BitmapShader 实战 实现圆形、圆角图片


    参考博客:

    Android Xfermode 实战实现圆形、圆角图片

    Android BitmapShader 实战 实现圆形、圆角图片

    推荐阅读

    一步步拆解 LeakCanary

    Android 面试必备 - http 与 https 协议

    Android 面试必备 - 计算机网络基本知识(TCP,UDP,Http,https)

    Android 面试必备 - 线程

    Android_interview github 地址

    扫一扫,欢迎关注我的微信公众号 stormjun94, 目前专注于 Android 开发,主要分享 Android开发相关知识和技术人成长历程,包括个人总结,职场经验,面试经验等。

    展开全文
  • 提取图像细节的两种方法

    千次阅读 2018-06-05 23:23:40
    一幅图像可以分解为两层:底层(base ...分解图像有两种方式,以下分别进行解释。 1. 加性分解 要获取图像的底层,即图像的低频信息,使用低通滤波(如均值滤波(mean filter),高斯滤波(gaussian filter),导向...

    一幅图像可以分解为两层:底层(base layer)和细节层(detail layer)。底层包含图像的低频信息,反映了图像在大尺度上的强度变化;细节层包含图像的高频信息,反映了图像在小尺度上的细节。分解图像有两种方式,以下分别进行解释。

    1. 加性分解

    要获取图像的底层,即图像的低频信息,使用低通滤波(如均值滤波(mean filter),高斯滤波(gaussian filter),导向滤波(guided filter))对图像进行滤波即可:

    B=f(I) B = f ( I )

    其中 I I 表示要分解的图像,f()表示低通滤波操作, B B 为提取的底层。

    提取底层后,使用源图像减去底层,即为细节层:

    D=IB

    其中 D D 表示提取的细节层。

    因为底层加上细节层即为源图像,所以我称此种分解方法为加性分解,对应于加性噪声。关于此种方法的应用,可以参见[1]。

    2. 乘性分解

    获取底层的方法与加性分解相同。然后使用源图像除以底层,即可得到细节层:

    D=I+ϵB+ϵ

    其中 ϵ ϵ 为一个很小的常数,以防止除零错误。

    因为底层乘以细节层即为源图像,所以我称此种分解方法为乘性分解,对应于乘性噪声。关于此种方法的应用,可以参见[2]。在其他文章中,此处得到的细节层也称为商图像(quotient image)[3]或比例图像(ratio image)[4]。

    3. 代码及效果

    // 图像细节提取。
    // 编程环境:Visual Studio Community 2015 + OpenCV 3.3.0
    #include "opencv2/core/core.hpp"
    #include "opencv2/imgcodecs/imgcodecs.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    
    int main()
    {
        cv::Mat I = cv::imread("im.png");
        if (I.empty())
        {
            return -1;
        }
    
        I.convertTo(I, CV_32FC3);
    
        cv::Mat B;
        cv::boxFilter(I, B, -1, cv::Size(31, 31));
    
        // 1. 加性分解
        cv::Mat D1 = I - B;
    
        // 2. 乘性分解
        const float epsilon = 1.0f;
        cv::Mat D2 = (I + epsilon) / (B + epsilon);
    
        // 显示图像
        I.convertTo(I, CV_8UC3);
        cv::imshow("源图像", I);
    
        B.convertTo(B, CV_8UC3);
        cv::imshow("Base layer", B);
    
        D1 = cv::abs(D1); // 因为包含负数,所以取绝对值
        D1.convertTo(D1, CV_8UC3);
        cv::imshow("Detail layer 1", D1);
    
        cv::normalize(D2, D2, 0.0, 255.0, cv::NORM_MINMAX); // 归一化
        D2.convertTo(D2, CV_8UC3);
        cv::imshow("Detail layer 2", D2);
    
        cv::waitKey();
        return 0;
    }

    图1:源图像
    图1:源图像
    图2:Base Layer
    图2:Base Layer
    图3:Detail Layer1
    图3:Detail Layer1
    图4:Detail Layer2
    图4:Detail Layer2

    4. 应用

    提取图像的细节层后,可以进行细节增强(detail enhancement)或细节转移(detail transfer)[2]等。

    5. 参考文献

    [1] S. Li, X. Kang, and J. Hu. Image fusion with guided fltering. IEEE Transactions on Image Processing, 22(7):2864–2875, July 2013.

    [2] Georg Petschnigg, Richard Szeliski, Maneesh Agrawala, Michael Cohen, Hugues Hoppe, and Kentaro Toyama. Digital photography with flash and no-flash image pairs. In ACM transactions on graphics (TOG), volume 23, pages 664–672. ACM, 2004.

    [3] Amnon Shashua and Tammy Riklin-Raviv. The quotient image: Class-based re-rendering and recognition with varying illuminations. IEEE Transactions on Pattern Analysis and Machine Intelligence, 23(2):129–139, 2001.

    [4] Zicheng Liu, Ying Shan, and Zhengyou Zhang. Expressive expression mapping with ratio images. In Proceedings of the 28th annual conference on Computer graphics and interactive techniques, pages 271–276. ACM, 2001.

    展开全文
  • MATLAB图像两种模糊模式

    千次阅读 2019-01-08 13:24:28
    下面为大家介绍一下如何利用inline和blkproc函数对图像进行模糊度采集和显示,具体步骤如下: 1、首先打开MATLAB,在其主界面的编辑器中写入下列代码: B=imread('tire.tif'); %读取图片 g=inline('uint8(round...

    下面为大家介绍一下如何利用inline和blkproc函数对图像进行模糊度采集和显示,具体步骤如下:

    1、首先打开MATLAB,在其主界面的编辑器中写入下列代码:

    B=imread('tire.tif');    %读取图片
    g=inline('uint8(round(mean2(x)*ones(size(x))))');
    B2=blkproc(B,[8 8],g);  %8*8的模糊度
    figure,imshow(B);    %显示原图
    figure,imshow(B2)    %显示第一种模糊度
    
    
    B=imread('tire.tif');    %读取图片
    g=inline('uint8(round(mean2(x)*ones(size(x))))');
    B2=blkproc(B,[8 8],[4 4],g);  %8*8/4*4的模糊度
    figure,imshow(B);     %显示原图
    figure,imshow(B2)     %显示第二种模糊度

    2、保存代码至自定义路径下,点击运行,结果如下:

     

    如图所示,在不同的模糊度下,图片所展示的样貌有明显区别,并可以按照我们想要的效果进行处理,只需选择适当的模糊度即可,请大家继续关注!!!

    展开全文
  • 用于图像融合的两种方法

    千次阅读 2011-09-17 12:52:12
    回顾曾经用过的两种图像融合方法: 小波融合: 1. 分解 首先将带融合的几幅图像分别进行小波分解:如果分解N层,则会形成3N+1个频带,其中3N个高频子图像,1个低频子图像。 2. 融合: 然后对各个子带图像分别...

    重拾记忆!回顾曾经用过的两种图像融合方法:

    小波融合:

    1. 分解

    首先将带融合的几幅图像分别进行小波分解:如果分解N层,则会形成3N+1个频带,其中3N个高频子图像,1个低频子图像。

    2. 融合:

    然后对各个子带图像分别进行融合:这里需要用到融合算子,有各种各样不同得融合算子。

    融合规则:1)加权平均2)选择最大值3)局域方差法4)局域能量法5)梯度法

    要求:图像是严格配准的

    高频段和低频段的图像融合规则分开。

    3. 重构:

    再对融合后的各个子带进行小波重构。

    小波基的种类和小波的分解层数对融合的效果影响很大。

     

    拉普拉斯金子塔融合:

    1. 首先对图像进行高斯金子塔分解:对第N层图像进行低通滤波,再进行下采样,得到第N+1层图像。如此迭代则可形成高斯金子塔。所形成的N+1层尺寸是第N成的1/4。

    2. 然后进行拉普拉斯金子塔分解:将第N+1层图像进行内插得到N*,然后用N-N*,得到LPN,即第N层拉普拉斯图像。其每一层图像是高斯金子塔本层图像与其高一层图形内插放大后的图像的差,该过程为一个带通滤波过程。拉普拉斯金子塔是一种带同金子塔分解。

    3. 最后是拉普拉斯金子塔重建图像:自顶向下进行递推,结合高斯金子塔得到原图像。

    通过拉普拉斯金子塔分解,将原图像分解到不同得空间频带上。

    4. 融合过程中,顶层图像的融合与其它层要分看看待。顶层图像采用平均梯度法:图像平均梯度越大,图像层次越丰富,则图像越清晰。其它层采用局域能量的融合规则。

    拉普拉斯梯度融合可以用于红外图像与可见光图像的融合中。

     

    图像融合效果的评判:

    1. 熵,即图像所包含的信息量

    2. 空间频率,反映图像全面活跃水平,频率越大,图像越清晰

    3. 平均梯度,平均梯度越大,图像越清晰。


    最后给出一个融合效果图,原图像采自老家~ 松滋 街河市


    对焦到左边的图像

    对焦到右边的图像

    融合后的图像(采用拉普拉斯梯度法进行融合)



    展开全文
  • 不同于传统的线性、非线性的只能增强图像某一类特征的方法,Retinex可以在动态范围压缩、边缘增强和颜色恒常三个方面达到平衡,因此可以对各种不同类型的图像进行自适应的增强。针对虹膜和光线比较有效。 参考地址 ...
  • OPENCV+MFC单文档显示图像两种方法

    万次阅读 2017-10-28 19:33:58
    OPENCV与MFC混合开发图像显示的两种方法:工程建好后,右击文档类选择建立类向导,选择虚函数中的OnOpenDocument,编辑在文档类里面添加Mat img;和string path;同时需要添加头文件#include&lt;opencv2/opencv....
  • 图像进行归一化的两种形式

    万次阅读 2019-08-05 16:20:56
    img = image/255.0 img = image/127.5 - 1 这两种图像处理方式都是进行归一化, 1、归一化的范围为【0,1】 还原:img * 255.0 2、范围为【-1,1】 还原:(img + 1.) * 127.5 ...
  • 在VisionPro中,使用工业相机采像的方式主要有两种: 通过调用CogAcqFifoTool工具的方式取像 通过实现 ICogAcqFifo接口获取图像 1. 通过CogAcqFifoTool工具取图: ① 连接相机到PC ② 修改相机和PC至同一网段,...
  • C#两种获取灰度图像的方法

    千次阅读 2013-03-11 19:24:59
    C#两种获取灰度图像的方法 第一种:在图像处理程序开发中,常会遇到将一幅彩色图像转换成灰度图像的情况,笔者在最近的一个项目中便遇到了这点。经过一翻努力最终解决,想想必要分享一下,于是便写下此文。在本文...
  • MFC两种拖动鼠标动态画图的方法

    万次阅读 2015-07-09 20:42:38
    要想在鼠标移动的过程中动态显示所画的图的变化过程,所画的图只能是可以由个点确定的图形,如直线、矩形、椭圆等等。举例来说,如何画一条线段?我们要知道起点和终点。起点自然是鼠标左键按下时鼠标的位置,终点...
  • itk 读取图像两种格式之间转换

    千次阅读 2016-04-11 21:02:31
    /************************************************************************ 控制台运行程序 输入: 程序名称 ... 图像在jpeg和bmp两种格式之间互换 **************************************
  • Matlab实现批量处理图像两种方法

    万次阅读 2017-01-03 09:02:51
    基本上有两个方法:一个是将你的图像统一进行一次重命名如:1.jpg,2.jpg等,然后利用for循环依次进行处理即可,如下面的语句:假设你的图像共有20副: str='D:\做差\好的图像\'; %我的图像放在D盘,做差文件夹下,...
  • 把微信头像保存到本地的两种方式

    千次阅读 2018-12-07 11:46:44
    怎么获取微信头像这里就不多做介绍了! 第一 public static void avatarUrl(String imageUrl) throws IOException { URL url = new URL(imageUrl); HttpsURLConnection con = (HttpsURLConnection) url....
  • 180512 python保存图像两种方法

    万次阅读 2018-05-12 14:21:39
    方法1 plt.imsave(file_path_name,your_numpy_array,cmap='gray') 方法2 plt.savefig('sprite.png',dpi=600)
  • 此次研究两种图像分割法,分别是基于形态学的分水岭算法和基于图割理论的GrabCut算法。OpenCV均提供了两张算法或其变种。鉴于研究所需,记录一些知识点,开发平台为OpenCV2.4.9+Qt5.3.2。 一、使用分水岭算法进行...
  • 两种无参考空间域图像噪点检测方法

    千次阅读 热门讨论 2017-09-26 11:51:11
    两种方法来源于Xinhao Liu和Masayuki Tanaka发表在IPIC上的三篇论文,先给出论文的链接: 《Noise Level Estimation Using Weak Textured Patches of a Single Noisy Image》 《Estimation Of Signal Dependent ...
  • 图像处理领域一个众所周知的结论:如果从图像中减去拉普拉斯算子部分,图像的边缘就会放大,因而图像会变的更加尖锐。 在这里基于拉普拉斯算子,通过访问图像中相邻像素来实现对图像的锐化 1、锐化原理公式 5*...
  • Android设置头像小案例,可以拍照也可以从本地选择,支持大图的裁剪,效果清晰,很不错哦!借鉴别人的例子:http://06peng.com/archives/192
  • 在Qt中处理图片一般都要用到QImage类,但是QImage的对象不能够直接显示出来,要想能看到图片,初步发现有两种方法。 一、QImage转QPixmap,然后用QLabel::setPixmap() image=new QImage("D:/Temp/XX.jpg"); ...
  • OpenCV2学习笔记(四):两种图像分割方法比较

    万次阅读 多人点赞 2015-02-23 16:16:44
    此次研究两种图像分割法,分别是基于形态学的分水岭算法和基于图割理论的GrabCut算法。OpenCV均提供了两张算法或其变种。鉴于研究所需,记录一些知识点,开发平台为OpenCV2.4.9+Qt5.3.2。
  • 两种图像分类算法和matlab源代码

    千次阅读 2015-08-17 16:40:06
    http://blog.sina.com.cn/s/blog_586cbcf70101asle.html
  • public class BaseActivity extends Activity { public void pickUpPic() { // 上面操作中的系统的图片的截取 } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data)...
  • 方法一:对每个像素点进行线性处理 两种常用的点过程(即点算子),是用常数对点进行乘法和加法运算:   两个参数 0" style="border:0px; m
  • 介绍 在使用matplotlib的过程中,发现不能像matlab一样同时开几个窗口进行比较,于是查询得知了...python可视化库matplotlib有两种显示模式: 阻塞(block)模式 交互(interactive)模式 在Python Consol命令...
  • 两种方法都是对二值图像操作的,思想都是从目标外围往目标中心, 利用以待检测像素为中心3*3像素窗口的特征,对目标不断腐蚀细化,直至腐蚀到不能再腐蚀(单层像素宽度),就得到了图像的骨架。下面详细介绍一下...
  • 【matplotlib】绘制动态图像

    千次阅读 多人点赞 2019-06-05 18:42:25
    利用matplotlib.animation 绘制动态图像 包括动态线和动态的二维图像结果显示
  • 在网上搜索半天,没有找到关于Sentech相机和halcon联合编程的例子,先将自己的代码发布如下. sentech相机驱动和sdk 下载地址  参考PvPipelineSample这...SDK获得图像类型是其自定义的 PvBuffer PvImage pvIma

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 593,540
精华内容 237,416
关键字:

动态图像有哪两种