具体实现:

0. 保存Bitmap到指定路径

参考网址android保存bitmap到指定路径

1. 加载资源图片

把PNG图片拖到工程中res中的drawable-hdpi中; (JPG需要转换格式到PNG)

InputStream is = getResources().openRawResource(R.drawable.pic_name); //图片名为pic_name.png
Bitmap bitmap = BitmapFactory.decodeStream(is);
ImageView.setImageBitmap(bitmap);

2. 加载系统图库图片

参考网址Android 如何从系统图库中选择图片

@Override
public void onClick(View view) {
		Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
		intent.setType("image/*");
		//intent.putExtra("crop", true); //裁剪图片
		intent.putExtra("return-data", true);
		startActivityForResult(intent, RESULT_LOAD_IMAGE);
}
...
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {

        Uri pic = data.getData();
        Log.d("onActivityResult", "chosen pic: " + pic.getPath());

        InputStream input = null;
      	try {
      		input = this.getActivity().getContentResolver().openInputStream(pic);
      	} catch (FileNotFoundException e) {
      		e.printStackTrace();
      	}

      	if(input != null) {
      		imageView.setImageBitmap(BitmapFactory.decodeStream(input));
      		imageView.setScaleType(ImageView.ScaleType.FIT_XY);
      	}
    }
}

3. bitmap转YUV

参考网址android bitmap转YUV

4. bitmap图片翻转(镜像)

垂直对称(y轴对称):

Matrix matrix = new Matrix();
float matrixValues[] = {-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f};
matrix.setValues(matrixValues);
//matrix.postTranslate(image.width, 0); //表示将图片左右倒置
matrix.postTranslate(width*2, 0);
canvas.drawBitmap(bitmap, matrix, paint);

参考网址Android图片旋转,缩放,位移,倾斜,对称完整示例(二)——Bitmap.createBitmap()和Matrix

5. bitmap图片缩放

Matrix matrix = new Matrix();
matrix.postScale(float sx, float sy);
canvas.drawBitmap(bitmap, matrix, paint);

6. argb数据生成Bitmap

Bitmap bitmap = Bitmap.createBitmap(bytes, width, height, Config.ARGB_8888);

7. 加载YUV Image

ByteArrayOutputStream out = new ByteArrayOutputStream();
YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, width, height, null);
yuvImage.compressToJpeg(new Rect(0, 0, width, height), 50, out);
byte[] imageBytes = out.toByteArray();
Bitmap image = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
imageview.setImageBitmap(image);

参考网址Displaying YUV Image in Android

or:

yuv420->rgb565/argb8888->bitmap对象->bmp图片

参考网址android yuv420数据保存为bmp图片

8. Bitmap图片旋转

/**
 * 读取图片的旋转的角度
 *
 * @param path 图片绝对路径
 *
 * @return 图片的旋转角度
 */
private int getBitmapDegree(String path) {
    int degree = 0;
    try {
        // 从指定路径下读取图片,并获取其EXIF信息
        ExifInterface exifInterface = new ExifInterface(path);
        // 获取图片的旋转信息
        int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);
        switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            degree = 90;
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            degree = 180;
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            degree = 270;
            break;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return degree;
}
/**
 * 将图片按照某个角度进行旋转
 *
 * @param bm 需要旋转的图片
 *
 * @param degree 旋转角度
 *
 * @return 旋转后的图片
 */
public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {
    Bitmap returnBm = null;
  
    // 根据旋转角度,生成旋转矩阵
    Matrix matrix = new Matrix();
    matrix.postRotate(degree);
    try {
        // 将原始图片按照旋转矩阵进行旋转,并得到新的图片
        returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
    } catch (OutOfMemoryError e) {
    }
    if (returnBm == null) {
        returnBm = bm;
    }
    if (bm != returnBm) {
        bm.recycle();
    }
    return returnBm;
}

参考网址

9. Bitmap压缩

方法一、采样率压缩

SDcard图片加载并压缩(decodeFile),参考网址:Android手机拍照上传被旋转90度的处理方法-getimage代码,代码如下:

public static Bitmap getImage(String srcPath) {  
    BitmapFactory.Options newOpts = new BitmapFactory.Options();  
    //开始读入图片,此时把options.inJustDecodeBounds 设回true了  
    newOpts.inJustDecodeBounds = true;  
    Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此时返回bitmap为空  
    
    int w = newOpts.outWidth; //图片宽
    int h = newOpts.outHeight;//图片高  
    //设置目标宽高。由于图片采用缩放比压缩,压缩后图片尺寸为近似目标宽高
    float ww = 480f;
    float hh = 800f;
    //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可  
    int be = 1; //be=1表示不缩放  
#if 0
    if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放  
        be = (int) (w / ww);  
    } else if (w < h && h > hh) {//如果高度高的话根据高度固定大小缩放  
        be = (int) (h / hh);  
    }  
    if (be <= 0) { 
        be = 1;
    }
#else // 缩放比为1, 2, 4, 8...
    if (w > h && w > ww) {
        be = Math.round(w / ww);
    } else if (w < h && h > hh) {
        be = Math.round(h / hh);
    }
    if (be <= 0) {
        be = 1;
    } else if (be > 1) {
    	double x = Math.log10(be) / Math.log10(2);
    	be = (int) Math.pow(2, Math.ceil(x));
    }
#endif
    
    newOpts.inSampleSize = be;//设置缩放比例
    newOpts.inJustDecodeBounds = false;  
    //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了  
    return BitmapFactory.decodeFile(srcPath, newOpts);  
}

图库图片加载并压缩(decodeStream),参考网址:decodeStream returns null(second invoke),代码如下:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
        Uri uri = data.getData();
        // String srcPath = uri.getPath();
        Bitmap bmp = getImage(uri);
    }
}

public static Bitmap getImage(Uri uri) {
    BitmapFactory.Options newOpts = new BitmapFactory.Options();
    newOpts.inJustDecodeBounds = true;
    
    InputStream is = null;
    try {
	is = this.getActivity().getContentResolver().openInputStream(uri);
    } catch (FileNotFoundException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
    }
    
    BitmapFactory.decodeStream(is, null, newOpts);

    int w = newOpts.outWidth;
    int h = newOpts.outHeight;
    float ww = EXPECTED_WIDTH; // 目标(期望)宽度
    float hh = EXPECTED_HEIGHT;// 目标(期望)高度

    int be = 1;
    if (w > h && w > ww) {
        be = Math.round(w / ww);
    } else if (w < h && h > hh) {
        be = Math.round(h / hh);
    }
    if (be <= 0) {
        be = 1;
    } else if (be > 1) {
    	double x = Math.log10(be) / Math.log10(2);
    	be = (int) Math.pow(2, Math.ceil(x));
    }

    newOpts.inSampleSize = be;
    newOpts.inJustDecodeBounds = false;
    
    InputStream isNew = null;
    try {
	isNew = this.getActivity().getContentResolver().openInputStream(uri);
    } catch (FileNotFoundException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
    }
    
    return BitmapFactory.decodeStream(isNew, null, newOpts);
}

方法二、缩放压缩(postScale)

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
        Uri uri = data.getData();

    InputStream is = null;
    try {
        is = this.getActivity().getContentResolver().openInputStream(uri);
    } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Bitmap bmp = BitmapFactory.decodeStream(is);

    int w = bmp.getWidth();
    int h = bmp.getHeight();
    float ww = EXPECTED_WIDTH; // 目标(期望)宽度
    float hh = EXPECTED_HEIGHT;// 目标(期望)高度

    Matrix matrix = new Matrix();
    matrix.postScale(ww/w, hh/h);
    Bitmap bitmap = Bitmap.createBitmap(bmp, 0, 0,  
    	bmp.getWidth(), bmp.getHeight(), matrix, true);
    }
}

参考网址android中bitmap压缩的几种方法的解读

10. Bitmap保存.bmp格式

参考网址

11. Bitmap转yuv420sp(NV21)

public static byte[] getYUV420sp(int inputWidth, int inputHeight, Bitmap scaled) {
    int[] argb = new int[inputWidth * inputHeight];
    scaled.getPixels(argb, 0, inputWidth, 0, 0, inputWidth, inputHeight);

    byte[] yuv = new byte[inputWidth * inputHeight * 3 / 2];
    encodeYUV420SP(yuv, argb, inputWidth, inputHeight);

    //scaled.recycle();
    return yuv;
}

private static void encodeYUV420SP(byte[] yuv420sp, int[] argb, int width, int height) {
    int Y, U, V;
    int yIndex = 0;

    int R, G, B;
    int argbIndex = 0;

    for (int j = 0; j < height; j++) {
        for (int i = 0; i < width; i++) {

            //int A = (argb[argbIndex] & 0xff000000) >> 24;
            R = (argb[argbIndex] & 0xff0000) >> 16;
            G = (argb[argbIndex] & 0xff00) >> 8;
            B = (argb[argbIndex] & 0xff);

            argbIndex++;

            // well known RGB to YUV algorithm
            Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
            U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
            V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;

            Y = Math.max(0, Math.min(Y, 255));
            U = Math.max(0, Math.min(U, 255));
            V = Math.max(0, Math.min(V, 255));

            // ---Y---
            yuv420sp[yIndex++] = (byte) Y;
        }
    }
}

12. 解决Android加载图片导致内存溢出

/*
 * scalSize: 缩小比例
 * eg,. scalSize = 10, width and height设为原来的1/10
 */
private Bitmap loadBitmap(String path, int scalSize) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = false;
    options.inSampleSize = scalSize;
    Bitmap bmp = BitmapFactory.decodeFile(path, options);
    return bmp;
}

参考网址: Android加载图片导致内存溢出(Out of Memory异常)

====================================================================

相关网址:

  1. android使用ImageView加载本地SdCard图片和加载网络图片

  2. 安卓开发-加载图片

  3. 怎样在android中添加背景图片