0

Android图片之处理圆形圆角

<h1>概述</h1>
<h2>图片格式概述:</h2>

BMP:高质量绘图 保证原图质量,用于相机等
BMP格式图片是有一个一个的像素点组成,每一个像素都是一个颜色.而每一个像素显示的颜色用的二进制位也不相同,这个像素位称之为位深,位深越大,表示每一个像素点所用的二进制位越多,显示的图像也就越清晰。
png:较高质量绘图 体积小,适用于网络传输
png图片是将bmp图片进行压缩,其压缩格式类似于rar压缩——将相同的byte信息合并表示。png图片可以还原,是无损的压缩方式。
jpg:良好的绘图质量 体积小,便于传输
jpg格式图片也是对bmp图片进行压缩,因为眼睛的精度是有限的,jpg利用这一点将很多颜色相近的用同一颜色标识,而对于一大块相同的颜色,则用一个值表示。jpg格式图片不能被还原。

<h2>加载大图</h2>

ImageView iv = (ImageView) findViewById(R.id.iv);
/**
 *  在Android中,每一个应用程序所占用的内存空间大小都会有一个固定的大小限制
 *  假设此处加载的图片是2560*1440像素,图片位深是24的jpg格式图像
 *  虽然此图占用的磁盘空间是1.3M,但图片在加载到内存中时,实际上会先转换成位图图像
 *  那么这张图片加载到内存中的大小就是2560*1440*32(位深24,windows系统中,使用24位字节表示一个颜色值:#000000,
 *  但在Android中,每一个颜色值是用32位字节表示一个颜色值:#00000000),因此,这张图片加载到内存中所需要占用的内存
 *  大小约为:14M,因此,占用内存是极大的.若是直接将图片加载到内存中,容易造成内存溢出
 *  解决方案:按比例压缩图片
 *按比例压缩图片首先就是要获取图片的大小
 * */
String path = "mnt/sdcard/1.jpg";
//用于设置图片渲染器参数

BitmapFactory.Options options = new Options();
//设置图片加载属性:不加载图片内容,只获取图片信息
options.inJustDecodeBounds = true;
//加载图片信息
BitmapFactory.decodeFile(path,options);
//获取图片宽高
int picwidth = options.outWidth;
int picheight = options.outHeight;
//获取屏幕大小
//获取窗口管理器
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);   
//获取默认显示设备
Display dis =wm.getDefaultDisplay();
//获取屏幕宽高
//dis.getSize(outSize);此方法适用于新版本Android系统
int diswidth = dis.getWidth();
int disheight = dis.getHeight();
//计算压缩比
int wr = picwidth/diswidth;
int hr = picheight/disheight;
int  r = 1;
if(wr>hr && wr>1){
  r = wr;
}
if(hr>wr && hr>1){
  r = hr;
}
//压缩图片
options.inSampleSize = r;//设置压缩比
options.inJustDecodeBounds = false;//设置加载图片内容
Bitmap bm = BitmapFactory.decodeFile(path,options);
iv.setImageBitmap(bm);

<h2>复制图像</h2>

ImageView iv = (ImageView) findViewById(R.id.iv);
/**
 *  复制图片:作用
 *  在Android中,直接从资源文件加载到的图片是不能进行操作的,只能进行显示
 *  想要进行操作,可以复制一张图片到内存,然后操作复制到的图片
 * */
//加载原图
Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/1.jpg");
//搞一个一样大小一样样式的复制图
Bitmap copybm = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
//获取复制图的画布
Canvas canvas = new Canvas(copybm);
//获取一个画笔,设置颜色
Paint paint = new Paint();
paint.setColor(Color.RED);
//向画布绘制,绘制原图内容
canvas.drawBitmap(bitmap, new Matrix(), paint);
//canvas.drawPoint(10, 10, paint); 向指定位置画一个点
iv.setImageBitmap(copybm);

<h2>图片旋转</h2>

ImageView iv = (ImageView) findViewById(R.id.iv);
/**
 *     图片旋转:
 *Android中原图是不能进行操作的,必须要先复制一张图到内存,然后再操作
 *旋转是在绘制过程中进行的
 * */
//加载原图
Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/1.jpg");
//搞一个一样大小一样样式的复制图
Bitmap copybm = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
//获取复制图的画布
Canvas canvas = new Canvas(copybm);
//获取一个画笔,设置颜色
Paint paint = new Paint();
paint.setColor(Color.RED);
//设置图片绘制角度——设置矩阵
Matrix matrix = new Matrix();
     /**       
matrix.setValues(new float[]{//这是矩阵的默认值
1.5f,0,0,
0,1,0,
0,0,1
});
而旋转其实是将每个点坐标和sinx  cosx进行计算...
    */
//安卓提供了便捷方法
matrix.setRotate(30,bitmap.getWidth()/2,bitmap.getHeight()/2);
//向画布绘制,绘制原图内容
canvas.drawBitmap(bitmap, matrix, paint);
//canvas.drawPoint(10, 10, paint); 向指定位置画一个点
iv.setImageBitmap(copybm);

<h2>改变图片大小和位置</h2>

ImageView iv = (ImageView) findViewById(R.id.iv);
//加载原图
Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/1.jpg");
//搞一个一样大小一样样式的复制图
Bitmap copybm = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
//获取复制图的画布
Canvas canvas = new Canvas(copybm);
//获取一个画笔,设置颜色
Paint paint = new Paint();
paint.setColor(Color.RED);
//设置图片绘制角度——设置矩阵
Matrix matrix = new Matrix();         
matrix.setValues(new float[]{//这是矩阵的默认值
1,0,0,
0,1,0,
0,0,1
});
/**
位置矩阵计算公式(以默认值为例,计算x、y、z轴的值):
x = 1x+0y+0z;
y = 0x+1y+0z;
z = 0x+0y+1z;
通过改变矩阵值可以修改图片
//图像的缩放也可以使用Android中自带的方法进行设置
matrix.setScale(0.5f, 0.5f);
    */
//向画布绘制,绘制原图内容
canvas.drawBitmap(bitmap, matrix, paint);
iv.setImageBitmap(copybm);

<h2>镜像</h2>

Matrix matrix = new Matrix();         
matrix.setValues(new float[]{//这是矩阵的默认值
-1,0,0,
0,1,0,
0,0,1
});
//镜像完还要平移回来
matrix.postTranslate(bitmap.getWidth(), 0);
//向画布绘制,绘制原图内容
canvas.drawBitmap(bitmap, matrix, paint);

<h2>倒影</h2>

Matrix matrix = new Matrix();         
matrix.setValues(new float[]{//这是矩阵的默认值
1,0,0,
0,-1,0,
0,0,1
});
//镜像完还要平移回来
matrix.postTranslate(0, bitmap.getHeight());
//向画布绘制,绘制原图内容
canvas.drawBitmap(bitmap, matrix, paint);
iv.setImageBitmap(copybm);

<h2>颜色处理</h2>

//加载原图
Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/1.jpg");
//搞一个一样大小一样样式的复制图
Bitmap copybm = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
//获取复制图的画布
Canvas canvas = new Canvas(copybm);
//获取一个画笔,设置颜色
Paint paint = new Paint();
paint.setColor(Color.RED);
ColorMatrix cm = new ColorMatrix();
cm.set(//默认颜色矩阵,通过修改rgba来对图片颜色进行处理
new float[]{
1,0,0,0,0,
0,1,0,0,0,
0,0,1,0,0,
0,0,0,1,0,
}
);
/*
颜色矩阵计算公式:
red   = 1*128 + 0*128 + 0*128 + 0*0 +0
blue  = 0*128 + 1*128 + 0*128 + 0*0 +0
green = 0*128 + 0*128 + 1*128 + 0*0 +0
alpha = 0*128 + 0*128 + 0*128 + 1*0 +0  透明度
*/
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(bitmap,new Matrix(), paint);
iv.setImageBitmap(copybm);

<h2>圆角图</h2>

public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {

        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
    }

<h2>图片添加倒影效果</h2>

/**
     * 获得带倒影的图片方法
     */
    public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {
        final int reflectionGap = 4;
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        Matrix matrix = new Matrix();
        matrix.preScale(1, -1);

        Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, height / 2,
                width, height / 2, matrix, false);

        Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
                (height + height / 2), Config.ARGB_8888);

        Canvas canvas = new Canvas(bitmapWithReflection);
        canvas.drawBitmap(bitmap, 0, 0, null);
        Paint deafalutPaint = new Paint();
        canvas.drawRect(0, height, width, height + reflectionGap, deafalutPaint);

        canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);

        Paint paint = new Paint();
        LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0,
                bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff,
                0x00ffffff, TileMode.CLAMP);
        paint.setShader(shader);
        // Set the Transfer mode to be porter duff and destination in
        paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
        // Draw a rectangle using the paint with our linear gradient
        canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
                + reflectionGap, paint);
        return bitmapWithReflection;
    }

<h2>添加水印</h2>

  /**
     * create the bitmap from a byte array 生成水印图片
     * 
     * @param src
     *            要添加水印的图片
     * @param 水印
     * @return 添加了水印的图片
     */
    private Bitmap createBitmap(Bitmap src, Bitmap watermark) {
        String tag = "createBitmap";
        Log.d(tag, "create a new bitmap");
        if (src == null) {
            return null;
        }

        int w = src.getWidth();
        int h = src.getHeight();
        int ww = watermark.getWidth();
        int wh = watermark.getHeight();
        // create the new blank bitmap
        Bitmap newb = Bitmap.createBitmap(w, h, Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图
        Canvas cv = new Canvas(newb);
        // draw src into
        cv.drawBitmap(src, 0, 0, null);// 在 0,0坐标开始画入src
        // draw watermark into
        cv.drawBitmap(watermark, w - ww + 5, h - wh + 5, null);// 在src的右下角画入水印
        // save all clip
        cv.save(Canvas.ALL_SAVE_FLAG);// 保存
        // store
        cv.restore();// 存储
        return newb;
    }

<h2>View转成Bitmap</h2>

 /**
     * 把一个View的对象转换成bitmap
     */
    static Bitmap getViewBitmap(View v) {

        v.clearFocus();
        v.setPressed(false);

        // 能画缓存就返回false
        boolean willNotCache = v.willNotCacheDrawing();
        v.setWillNotCacheDrawing(false);
        int color = v.getDrawingCacheBackgroundColor();
        v.setDrawingCacheBackgroundColor(0);
        if (color != 0) {
            v.destroyDrawingCache();
        }
        v.buildDrawingCache();
        Bitmap cacheBitmap = v.getDrawingCache();
        if (cacheBitmap == null) {
            Log.e(TAG, "failed getViewBitmap(" + v + ")",
                    new RuntimeException());
            return null;
        }
        Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
        // Restore the view
        v.destroyDrawingCache();
        v.setWillNotCacheDrawing(willNotCache);
        v.setDrawingCacheBackgroundColor(color);
        return bitmap;
    }

转自:https://www.jianshu.com/p/fe1955cdbc1f

天边的星星