直接上代码:
CameraView.java
package com.cameraView;
import imageUtil.ImageUtil;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.ShutterCallback;
import android.hardware.Camera.Size;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;import com.Camera.CameraActivity;
import com.Filters.R;public class CameraView extends SurfaceView implements Callback {
SurfaceHolder mSurfaceHolder;
Camera mCamera = null;Context mContext;
private final int cameraId = 0;
private int imageType = 0;private Handler mHandler;
private ShutterCallback shutter = new ShutterCallback() {public void onShutter() {
}
};public void setHandle(Handler handler) {
mHandler = handler;
}private PictureCallback raw = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
}
};
private PictureCallback jpeg = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
try {
Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length);
Log.i("length", "" + data.length);
Log.i("data[0]", "" + data[0]);
System.out.println("length = "+ data.length + ",data = " + data[0]);
// ImageUtil.saveToLocal(bm);
// ImageUtil.SaveBitmap(bm,"test.jpg");
// ImageUtil.savePicInLocal(bm);
// File file = new File(Environment.getExternalStorageDirectory()+"/test.jpg");
// FileOutputStream outStream = new FileOutputStream(file);
// bm.compress(CompressFormat.JPEG, 100, outStream);
// outStream.flush();
// outStream.close();
Bitmap bitmap = imageUtil.ImageUtil.postRotateBitamp(bm, 90f);
Message message = new Message();
message.what = 1034;
message.obj = bitmap;
mHandler.sendMessage(message); // 显示图片
} catch (Exception e) {
e.printStackTrace();
}}
};private PreviewCallback mPreviewCallback = new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
// if (data != null) {
// int imageWidth = mCamera.getParameters().getPreviewSize().width;
// int imageHeight = mCamera.getParameters().getPreviewSize().height;
// int RGBData[] = new int[imageWidth * imageHeight];
// decodeYUV420SP(RGBData, data, imageWidth, imageHeight); // 解码
// Bitmap bm = Bitmap.createBitmap(RGBData, imageWidth, imageHeight, Config.ARGB_8888);
//// bm = imageUtil.ImageUtil.toGrayscale(bm);// 实时滤镜效果 这时把图片变成黑白
//// bm = imageUtil.ImageUtil.film(bm);// 实时滤镜效果 这时把图片变成黑白
// bm = getImageBitmapByType(bm,imageType);
// Message message = new Message();
// message.what = 1033;
// message.obj = bm;
// mHandler.sendMessage(message); // 显示图片
// }
}
};private AutoFocusCallback autoFocus = new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
// TODO Auto-generated method stub}
};/**
* 拍照
*/
public void tackPicture() {
mCamera.takePicture(shutter, raw, jpeg);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
mCamera.startPreview();
mCamera.autoFocus(autoFocus);
}
}, 1500);
}/**
* 解码
*
* @param rgb
* @param yuv420sp
* @param width
* @param height
*/
static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
final int frameSize = width * height;for (int j = 0, yp = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0)
y = 0;
if ((i & 1) == 0) {
v = (0xff & yuv420sp[uvp++]) - 128;
u = (0xff & yuv420sp[uvp++]) - 128;
}int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192 - 833 * v - 400 * u);
int b = (y1192 + 2066 * u);if (r < 0)
r = 0;
else if (r > 262143)
r = 262143;
if (g < 0)
g = 0;
else if (g > 262143)
g = 262143;
if (b < 0)
b = 0;
else if (b > 262143)
b = 262143;rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
}
}
}public void startCamera() {
mCamera.startPreview();
}public void stopCamera() {
if (mCamera != null) {
mCamera.stopPreview();
}
}public CameraView(Context context) {
super(context);
// TODO Auto-generated constructor stub
mSurfaceHolder = getHolder();// 获得surfaceHolder引用
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// 设置类型
mContext = context;
}public CameraView(Context context, AttributeSet attrs) {
super(context, attrs);
mSurfaceHolder = getHolder();// 获得surfaceHolder引用
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// 设置类型
mContext = context;}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters parameters = mCamera.getParameters();// 获得相机参数
// parameters.setPreviewSize(width, height); // 设置预览图像大小
parameters.setPictureFormat(PixelFormat.JPEG); // 设置照片格式
// if (CameraActivity.ScreenOrient(CameraActivity.activity) ==
// Configuration.ORIENTATION_LANDSCAPE) {
// Log.i("横屏", "横屏");
// mCamera.setDisplayOrientation(0);
// } else if (CameraActivity.ScreenOrient(CameraActivity.activity) ==
// Configuration.ORIENTATION_PORTRAIT) {
// Log.i("素屏", "素屏");
// mCamera.setDisplayOrientation(90);
// }
// 取得相机所支持多少图片大小的个数
List<Size> pszize = parameters.getSupportedPreviewSizes();
// List<Size> pszize = parameters.getSupportedPictureSizes();
if (null != pszize && 0 < pszize.size()) {
int height1[] = new int[pszize.size()];// 声明一个数组
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < pszize.size(); i++) {
Size size = (Size) pszize.get(i);
int sizeheight = size.height;
int sizewidth = size.width;
height1[i] = sizeheight;
map.put(sizeheight, sizewidth);
}
Arrays.sort(height1);
// 设置
// parameters.setPictureSize(map.get(height[0]),height[0]);
parameters.setPreviewSize(map.get(height1[0]),height1[0]);
}
mCamera.setDisplayOrientation(CameraActivity.curDregree(cameraId));
mCamera.setParameters(parameters);// 设置相机参数mCamera.startPreview();
mCamera.autoFocus(autoFocus);
}public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (mCamera == null) {
mCamera = Camera.open(cameraId);// 开启相机,不能放在构造函数中,不然不会显示画面.
mCamera.setPreviewCallback(mPreviewCallback);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
mCamera.stopPreview();// 停止预览
mCamera.release();// 释放相机资源
mCamera = null;
}private Bitmap getImageBitmapByType(Bitmap bm,int type){
Bitmap bitmap = imageUtil.ImageUtil.postRotateBitamp(bm, 90f);
switch (type) {
case 0:
return imageUtil.ImageUtil.toGrayscale(bitmap);//滤镜
case 1:
return imageUtil.ImageUtil.blurImage(bitmap);//模糊
case 2:
return imageUtil.ImageUtil.blurImageAmeliorate(bitmap);//柔化(高斯模糊)
case 3:
return imageUtil.ImageUtil.doodle(bitmap, ImageUtil.readBitMap(mContext, R.drawable.ic_launcher),
bitmap.getWidth() / 2, bitmap.getHeight() / 2);//涂鸦
case 4:
return imageUtil.ImageUtil.emboss(bitmap);//浮雕
case 5:
return imageUtil.ImageUtil.film(bitmap);//底片
case 6:
return imageUtil.ImageUtil.getRoundedCornerBitmap(bm, 2.0f);//圆角
case 7:
return imageUtil.ImageUtil.oldRemeber(bitmap);//怀旧
case 8:
return imageUtil.ImageUtil.postRotateBitamp(bm, 90f);//旋转
case 9:
return imageUtil.ImageUtil.reverseBitmap(bitmap, 0);//反转
case 10:
return imageUtil.ImageUtil.sharpenImageAmeliorate(bitmap);//锐化
case 11:
return imageUtil.ImageUtil.sketch(bitmap);//素描
case 12:
return imageUtil.ImageUtil.sunshine(bitmap, bitmap.getWidth() / 2, bitmap.getHeight() / 2);//光照
}
return imageUtil.ImageUtil.toGrayscale(bitmap);
}public int getImageType() {
return imageType;
}public void setImageType(int imageType) {
this.imageType = imageType;
}
}
CameraActivity.java
ImageUtil这个类是处理图片变化的核心类:package com.Camera;
import imageUtil.ImageUtil;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Display;
import android.view.Surface;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Spinner;
import com.Filters.R;
import com.cameraView.CameraView;
public class CameraActivity extends Activity implements OnClickListener {
/** Called when the activity is first created. */
ImageView imageView;
boolean isClicked = false;
CameraView mCameraView;
Button btn1, btn2, btn3;
private Spinner spinner;
private Bitmap bitmap;
private int pos;
private String[] types = {
"滤镜", "模糊", "柔化(高斯模糊)", "涂鸦", "浮雕",
"底片", "圆角", "怀旧", "旋转",
"反转" ,"锐化", "素描", "光照",
"图片色调饱和度、色相、亮度处理"
};
public static Activity activity = null;
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == 1033) {
Bitmap bitmap = (Bitmap)msg.obj;
imageView.setImageBitmap(bitmap);
}else if (msg.what == 1034) {
bitmap = (Bitmap)msg.obj;
// imageView.setImageBitmap(bitmap);
mCameraView.stopCamera();
mCameraView.setBackgroundDrawable(ImageUtil.bitmapToDrawable(bitmap));
Bitmap bit = getImageBitmapByType(bitmap,pos);
Message message = new Message();
message.what = 1033;
message.obj = bit;
mHandler.sendMessage(message); // 显示图片
}
};
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
activity = this;
findView();
}
private void findView() {
btn1 = (Button) findViewById(R.id.myButton1);
btn2 = (Button) findViewById(R.id.myButton2);
btn3 = (Button) findViewById(R.id.myButton3);
imageView = (ImageView)findViewById(R.id.myImageView1);
mCameraView = (CameraView) findViewById(R.id.mSurfaceView1);
mCameraView.setHandle(mHandler);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
btn3.setOnClickListener(this);
spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.item, R.id.textViewForItem, types);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
// mCameraView.stopCamera();
// mCameraView.setImageType(arg2);
// mCameraView.startCamera();
pos = arg2;
if(bitmap != null){
if(arg2 == 13){
Intent intent = new Intent(CameraActivity.this,ImageToneActivity.class);
intent.putExtra("bitmap", ImageUtil.Bitmap2Bytes(bitmap));
startActivity(intent);
}else{
Bitmap bit = getImageBitmapByType(bitmap,arg2);
Message message = new Message();
message.what = 1033;
message.obj = bit;
mHandler.sendMessage(message); // 显示图片
}
}
}
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
}
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.myButton1:
mCameraView.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
mCameraView.startCamera();
break;
case R.id.myButton2:
mCameraView.stopCamera();
break;
case R.id.myButton3:
mCameraView.tackPicture();
break;
default:
break;
}
}
public static int ScreenOrient(Activity activity) {
int orient = activity.getRequestedOrientation();
if (orient != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE && orient != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
// 宽>高为横屏,反正为竖屏
WindowManager windowManager = activity.getWindowManager();
Display display = windowManager.getDefaultDisplay();
int screenWidth = display.getWidth();
int screenHeight = display.getHeight();
orient = screenWidth < screenHeight ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
: ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
}
return orient;
}
public static int curDregree(int cameraId) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
return result;
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
System.exit(0);
}
private Bitmap getImageBitmapByType(Bitmap bm,int type){
switch (type) {
case 0:
return imageUtil.ImageUtil.toGrayscale(bitmap);//滤镜
case 1:
return imageUtil.ImageUtil.blurImage(bitmap);//模糊
case 2:
return imageUtil.ImageUtil.blurImageAmeliorate(bitmap);//柔化(高斯模糊)
case 3:
return imageUtil.ImageUtil.doodle(bitmap, ImageUtil.readBitMap(this, R.drawable.ic_launcher),
bitmap.getWidth() / 2, bitmap.getHeight() / 2);//涂鸦
case 4:
return imageUtil.ImageUtil.emboss(bitmap);//浮雕
case 5:
return imageUtil.ImageUtil.film(bitmap);//底片
case 6:
return imageUtil.ImageUtil.getRoundedCornerBitmap(bm, 2.0f);//圆角
case 7:
return imageUtil.ImageUtil.oldRemeber(bitmap);//怀旧
case 8:
return imageUtil.ImageUtil.postRotateBitamp(bm, 90f);//旋转
case 9:
return imageUtil.ImageUtil.reverseBitmap(bitmap, 0);//反转
case 10:
return imageUtil.ImageUtil.sharpenImageAmeliorate(bitmap);//锐化
case 11:
return imageUtil.ImageUtil.sketch(bitmap);//素描
case 12:
return imageUtil.ImageUtil.sunshine(bitmap, bitmap.getWidth() / 2, bitmap.getHeight() / 2);//光照
}
return imageUtil.ImageUtil.toGrayscale(bitmap);
}
}
package imageUtil;ToneLayer类是对图片色调的处理:
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.util.Log;
public class ImageUtil {
// 放大缩小图片
public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix matrix = new Matrix();
float scaleWidht = ((float) w / width);
float scaleHeight = ((float) h / height);
matrix.postScale(scaleWidht, scaleHeight);
Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
return newbmp;
}
// 将Drawable转化为Bitmap
public static Bitmap drawableToBitmap(Drawable drawable) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height,
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, width, height);
drawable.draw(canvas);
return bitmap;
}
/**
* bitmap转换为drawable
* @param bitmap
* @return
*/
public static Drawable bitmapToDrawable(Bitmap bitmap){
Drawable drawable = new BitmapDrawable(bitmap);
return drawable;
}
/**
* bitmap转换为byte
* @param bm
* @return
*/
public static byte[] Bitmap2Bytes(Bitmap bm){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
return baos.toByteArray();
}
public static String SaveBitmap(Bitmap bmp, String name) {
File file = new File("mnt/sdcard/picture/");
String path = null;
if (!file.exists())
file.mkdirs();
try {
path = file.getPath() + "/" + name;
FileOutputStream fileOutputStream = new FileOutputStream(path);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
System.out.println("saveBmp is here");
} catch (Exception e) {
e.printStackTrace();
}
return path;
}
public static void savePicInLocal(Bitmap bitmap) {
FileOutputStream fos = null;
BufferedOutputStream bos = null;
ByteArrayOutputStream baos = null; // 字节数组输出流
try {
baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] byteArray = baos.toByteArray();// 字节数组输出流转换成字节数组
String saveDir = Environment.getExternalStorageDirectory() + "/pic";
File dir = new File(saveDir);
if (!dir.exists()) {
dir.mkdir(); // 创建文件夹
System.out.println("dir is not exist");
}
String fileName = saveDir + "/" + "test.png";
System.out.println("fileName = " + fileName);
File file = new File(fileName);
// file.delete();
if (!file.exists()) {
System.out.println("file is not exist!!!!");
file.createNewFile();// 创建文件
Log.e("PicDir", file.getPath());
// Toast.makeText(TackPhoto.this, fileName, Toast.LENGTH_LONG)
// .show();
}
// 将字节数组写入到刚创建的图片文件中
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(byteArray);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (baos != null) {
try {
baos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (bos != null) {
try {
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static String saveToLocal(Bitmap bm) {
String path = "/sdcard/test.jpg";
try {
FileOutputStream fos = new FileOutputStream(path);
bm.compress(CompressFormat.JPEG, 75, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
System.out.println("FileNotFoundException = " + e.toString());
Log.e("save", "FileNotFoundException = " + e.toString());
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
System.out.println("IOException = " + e.toString());
Log.e("save", "IOException = " + e.toString());
return null;
}catch(Exception e){
Log.e("save", "Exception = " + e.toString());
}
return path;
}
// 获得圆角图片的方法
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;
}
// 获得带倒影的图片方法
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;
}
/**
* 读取资源图片
*
* @param context
* @param resId
* @return
*/
public static Bitmap readBitMap(Context context, int resId) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
// 获取资源图片
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opt);
}
/**
* 从sd卡读取图片
*
* @param path
* @return
*/
public static Bitmap readBitMap(String path) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Config.ARGB_8888;
Bitmap bm = BitmapFactory.decodeFile(path, options);
return bm;
}
/**
* 图片旋转
*
* @param bmp
* @param degree
* @return
*/
public static Bitmap postRotateBitamp(Bitmap bmp, float degree) {
// 获得Bitmap的高和宽
int bmpWidth = bmp.getWidth();
int bmpHeight = bmp.getHeight();
// 产生resize后的Bitmap对象
Matrix matrix = new Matrix();
matrix.postRotate(degree);
Bitmap resizeBmp = Bitmap.createBitmap(bmp, 0, 0, bmpWidth, bmpHeight, matrix, true);
return resizeBmp;
}
// 图片翻转
public static Bitmap reverseBitmap(Bitmap bmp, int flag) {
float[] floats = null;
switch (flag) {
case 0: // 水平反转
floats = new float[] { -1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f };
break;
case 1: // 垂直反转
floats = new float[] { 1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f };
break;
}
if (floats != null) {
Matrix matrix = new Matrix();
matrix.setValues(floats);
return Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
}
return bmp;
}
/**
* 组合涂鸦图片和源图片
*
* @param src
* 源图片
* @param watermark
* 涂鸦图片
* @return
*/
public static Bitmap doodle(Bitmap src, Bitmap watermark, int x, int y) {
// 另外创建一张图片
Bitmap newb = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图
Canvas canvas = new Canvas(newb);
canvas.drawBitmap(src, 0, 0, null);// 在 0,0坐标开始画入原图片src
canvas.drawBitmap(watermark, (src.getWidth() - watermark.getWidth()) / 2,
(src.getHeight() - watermark.getHeight()) / 2, null); // 涂鸦图片画到原图片中间位置
canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.restore();
watermark.recycle();
watermark = null;
return newb;
}
/**
* 图片上写文字
*
* @param src源图片
* @param msg文字
* @param x
* @param y
* @return
*/
public static Bitmap drawText(Bitmap src, String msg, int x, int y) {
// 另外创建一张图片
Canvas canvas = new Canvas(src);
Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawText(msg, x, y, paint);
canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.restore();
return src;
}
public static Bitmap oldRemeber(Bitmap bmp) {
if (ImageCache1.get("oldRemeber") != null) {
return ImageCache1.get("oldRemeber");
}
// 速度测试
long start = System.currentTimeMillis();
int width = bmp.getWidth();
int height = bmp.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
int pixColor = 0;
int pixR = 0;
int pixG = 0;
int pixB = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int[] pixels = new int[width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
for (int i = 0; i < height; i++) {
for (int k = 0; k < width; k++) {
pixColor = pixels[width * i + k];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
newR = (int) (0.393 * pixR + 0.769 * pixG + 0.189 * pixB);
newG = (int) (0.349 * pixR + 0.686 * pixG + 0.168 * pixB);
newB = (int) (0.272 * pixR + 0.534 * pixG + 0.131 * pixB);
int newColor = Color.argb(255, newR > 255 ? 255 : newR, newG > 255 ? 255 : newG, newB > 255 ? 255
: newB);
pixels[width * i + k] = newColor;
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
long end = System.currentTimeMillis();
Log.e("may", "used time=" + (end - start));
ImageCache1.put("oldRemeber", bitmap);
return bitmap;
}
/**
* 模糊效果
*
* @param bmp
* @return
*/
public static Bitmap blurImage(Bitmap bmp) {
if (ImageCache1.get("blurImage") != null) {
return ImageCache1.get("blurImage");
}
// 速度测试
long start = System.currentTimeMillis();
int width = bmp.getWidth();
int height = bmp.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
int pixColor = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int newColor = 0;
int[][] colors = new int[9][3];
for (int i = 1, length = width - 1; i < length; i++) {
for (int k = 1, len = height - 1; k < len; k++) {
for (int m = 0; m < 9; m++) {
int s = 0;
int p = 0;
switch (m) {
case 0:
s = i - 1;
p = k - 1;
break;
case 1:
s = i;
p = k - 1;
break;
case 2:
s = i + 1;
p = k - 1;
break;
case 3:
s = i + 1;
p = k;
break;
case 4:
s = i + 1;
p = k + 1;
break;
case 5:
s = i;
p = k + 1;
break;
case 6:
s = i - 1;
p = k + 1;
break;
case 7:
s = i - 1;
p = k;
break;
case 8:
s = i;
p = k;
}
pixColor = bmp.getPixel(s, p);
colors[m][0] = Color.red(pixColor);
colors[m][1] = Color.green(pixColor);
colors[m][2] = Color.blue(pixColor);
}
for (int m = 0; m < 9; m++) {
newR += colors[m][0];
newG += colors[m][1];
newB += colors[m][2];
}
newR = (int) (newR / 9F);
newG = (int) (newG / 9F);
newB = (int) (newB / 9F);
newR = Math.min(255, Math.max(0, newR));
newG = Math.min(255, Math.max(0, newG));
newB = Math.min(255, Math.max(0, newB));
newColor = Color.argb(255, newR, newG, newB);
bitmap.setPixel(i, k, newColor);
newR = 0;
newG = 0;
newB = 0;
}
}
long end = System.currentTimeMillis();
Log.e("blurImage()", "used time=" + (end - start));
ImageCache1.put("blurImage", bitmap);
return bitmap;
}
/**
* 柔化效果(高斯模糊)(优化后比上面快三倍)
*
* @param bmp
* @return
*/
public static Bitmap blurImageAmeliorate(Bitmap bmp) {
if (ImageCache1.get("blurImageAmeliorate") != null) {
return ImageCache1.get("blurImageAmeliorate");
}
long start = System.currentTimeMillis();
// 高斯矩阵
int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 };
int width = bmp.getWidth();
int height = bmp.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
int pixR = 0;
int pixG = 0;
int pixB = 0;
int pixColor = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int delta = 16; // 值越小图片会越亮,越大则越暗
int idx = 0;
int[] pixels = new int[width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
for (int i = 1, length = height - 1; i < length; i++) {
for (int k = 1, len = width - 1; k < len; k++) {
idx = 0;
for (int m = -1; m <= 1; m++) {
for (int n = -1; n <= 1; n++) {
pixColor = pixels[(i + m) * width + k + n];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
newR = newR + (int) (pixR * gauss[idx]);
newG = newG + (int) (pixG * gauss[idx]);
newB = newB + (int) (pixB * gauss[idx]);
idx++;
}
}
newR /= delta;
newG /= delta;
newB /= delta;
newR = Math.min(255, Math.max(0, newR));
newG = Math.min(255, Math.max(0, newG));
newB = Math.min(255, Math.max(0, newB));
pixels[i * width + k] = Color.argb(255, newR, newG, newB);
newR = 0;
newG = 0;
newB = 0;
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
long end = System.currentTimeMillis();
Log.d("blurImageAmeliorate", "used time=" + (end - start));
ImageCache1.put("blurImageAmeliorate", bitmap);
return bitmap;
}
public static Bitmap sketch(Bitmap bmp) {
if (ImageCache1.get("sketch") != null) {
return ImageCache1.get("sketch");
}
long start = System.currentTimeMillis();
int pos, row, col, clr;
int width = bmp.getWidth();
int height = bmp.getHeight();
int[] pixSrc = new int[width * height];
int[] pixNvt = new int[width * height];
// 先对图象的像素处理成灰度颜色后再取反
bmp.getPixels(pixSrc, 0, width, 0, 0, width, height);
for (row = 0; row < height; row++) {
for (col = 0; col < width; col++) {
pos = row * width + col;
pixSrc[pos] = (Color.red(pixSrc[pos]) + Color.green(pixSrc[pos]) + Color.blue(pixSrc[pos])) / 3;
pixNvt[pos] = 255 - pixSrc[pos];
}
}
// 对取反的像素进行高斯模糊, 强度可以设置,暂定为5.0
gaussGray(pixNvt, 5.0, 5.0, width, height);
// 灰度颜色和模糊后像素进行差值运算
for (row = 0; row < height; row++) {
for (col = 0; col < width; col++) {
pos = row * width + col;
clr = pixSrc[pos] << 8;
clr /= 256 - pixNvt[pos];
clr = Math.min(clr, 255);
pixSrc[pos] = Color.rgb(clr, clr, clr);
}
}
bmp.setPixels(pixSrc, 0, width, 0, 0, width, height);
long end = System.currentTimeMillis();
Log.d("blurImageAmeliorate", "used time=" + (end - start));
ImageCache1.put("sketch", bmp);
return bmp;
}
private static int gaussGray(int[] psrc, double horz, double vert, int width, int height) {
int[] dst, src;
double[] n_p, n_m, d_p, d_m, bd_p, bd_m;
double[] val_p, val_m;
int i, j, t, k, row, col, terms;
int[] initial_p, initial_m;
double std_dev;
int row_stride = width;
int max_len = Math.max(width, height);
int sp_p_idx, sp_m_idx, vp_idx, vm_idx;
val_p = new double[max_len];
val_m = new double[max_len];
n_p = new double[5];
n_m = new double[5];
d_p = new double[5];
d_m = new double[5];
bd_p = new double[5];
bd_m = new double[5];
src = new int[max_len];
dst = new int[max_len];
initial_p = new int[4];
initial_m = new int[4];
// 垂直方向
if (vert > 0.0) {
vert = Math.abs(vert) + 1.0;
std_dev = Math.sqrt(-(vert * vert) / (2 * Math.log(1.0 / 255.0)));
// 初试化常量
findConstants(n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev);
for (col = 0; col < width; col++) {
for (k = 0; k < max_len; k++) {
val_m[k] = val_p[k] = 0;
}
for (t = 0; t < height; t++) {
src[t] = psrc[t * row_stride + col];
}
sp_p_idx = 0;
sp_m_idx = height - 1;
vp_idx = 0;
vm_idx = height - 1;
initial_p[0] = src[0];
initial_m[0] = src[height - 1];
for (row = 0; row < height; row++) {
terms = (row < 4) ? row : 4;
for (i = 0; i <= terms; i++) {
val_p[vp_idx] += n_p[i] * src[sp_p_idx - i] - d_p[i] * val_p[vp_idx - i];
val_m[vm_idx] += n_m[i] * src[sp_m_idx + i] - d_m[i] * val_m[vm_idx + i];
}
for (j = i; j <= 4; j++) {
val_p[vp_idx] += (n_p[j] - bd_p[j]) * initial_p[0];
val_m[vm_idx] += (n_m[j] - bd_m[j]) * initial_m[0];
}
sp_p_idx++;
sp_m_idx--;
vp_idx++;
vm_idx--;
}
transferGaussPixels(val_p, val_m, dst, 1, height);
for (t = 0; t < height; t++) {
psrc[t * row_stride + col] = dst[t];
}
}
}
// 水平方向
if (horz > 0.0) {
horz = Math.abs(horz) + 1.0;
if (horz != vert) {
std_dev = Math.sqrt(-(horz * horz) / (2 * Math.log(1.0 / 255.0)));
// 初试化常量
findConstants(n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev);
}
for (row = 0; row < height; row++) {
for (k = 0; k < max_len; k++) {
val_m[k] = val_p[k] = 0;
}
for (t = 0; t < width; t++) {
src[t] = psrc[row * row_stride + t];
}
sp_p_idx = 0;
sp_m_idx = width - 1;
vp_idx = 0;
vm_idx = width - 1;
initial_p[0] = src[0];
initial_m[0] = src[width - 1];
for (col = 0; col < width; col++) {
terms = (col < 4) ? col : 4;
for (i = 0; i <= terms; i++) {
val_p[vp_idx] += n_p[i] * src[sp_p_idx - i] - d_p[i] * val_p[vp_idx - i];
val_m[vm_idx] += n_m[i] * src[sp_m_idx + i] - d_m[i] * val_m[vm_idx + i];
}
for (j = i; j <= 4; j++) {
val_p[vp_idx] += (n_p[j] - bd_p[j]) * initial_p[0];
val_m[vm_idx] += (n_m[j] - bd_m[j]) * initial_m[0];
}
sp_p_idx++;
sp_m_idx--;
vp_idx++;
vm_idx--;
}
transferGaussPixels(val_p, val_m, dst, 1, width);
for (t = 0; t < width; t++) {
psrc[row * row_stride + t] = dst[t];
}
}
}
return 0;
}
private static void findConstants(double[] n_p, double[] n_m, double[] d_p, double[] d_m, double[] bd_p,
double[] bd_m, double std_dev) {
double div = Math.sqrt(2 * 3.141593) * std_dev;
double x0 = -1.783 / std_dev;
double x1 = -1.723 / std_dev;
double x2 = 0.6318 / std_dev;
double x3 = 1.997 / std_dev;
double x4 = 1.6803 / div;
double x5 = 3.735 / div;
double x6 = -0.6803 / div;
double x7 = -0.2598 / div;
int i;
n_p[0] = x4 + x6;
n_p[1] = (Math.exp(x1) * (x7 * Math.sin(x3) - (x6 + 2 * x4) * Math.cos(x3)) + Math.exp(x0)
* (x5 * Math.sin(x2) - (2 * x6 + x4) * Math.cos(x2)));
n_p[2] = (2
* Math.exp(x0 + x1)
* ((x4 + x6) * Math.cos(x3) * Math.cos(x2) - x5 * Math.cos(x3) * Math.sin(x2) - x7 * Math.cos(x2)
* Math.sin(x3)) + x6 * Math.exp(2 * x0) + x4 * Math.exp(2 * x1));
n_p[3] = (Math.exp(x1 + 2 * x0) * (x7 * Math.sin(x3) - x6 * Math.cos(x3)) + Math.exp(x0 + 2 * x1)
* (x5 * Math.sin(x2) - x4 * Math.cos(x2)));
n_p[4] = 0.0;
d_p[0] = 0.0;
d_p[1] = -2 * Math.exp(x1) * Math.cos(x3) - 2 * Math.exp(x0) * Math.cos(x2);
d_p[2] = 4 * Math.cos(x3) * Math.cos(x2) * Math.exp(x0 + x1) + Math.exp(2 * x1) + Math.exp(2 * x0);
d_p[3] = -2 * Math.cos(x2) * Math.exp(x0 + 2 * x1) - 2 * Math.cos(x3) * Math.exp(x1 + 2 * x0);
d_p[4] = Math.exp(2 * x0 + 2 * x1);
for (i = 0; i <= 4; i++) {
d_m[i] = d_p[i];
}
n_m[0] = 0.0;
for (i = 1; i <= 4; i++) {
n_m[i] = n_p[i] - d_p[i] * n_p[0];
}
double sum_n_p, sum_n_m, sum_d;
double a, b;
sum_n_p = 0.0;
sum_n_m = 0.0;
sum_d = 0.0;
for (i = 0; i <= 4; i++) {
sum_n_p += n_p[i];
sum_n_m += n_m[i];
sum_d += d_p[i];
}
a = sum_n_p / (1.0 + sum_d);
b = sum_n_m / (1.0 + sum_d);
for (i = 0; i <= 4; i++) {
bd_p[i] = d_p[i] * a;
bd_m[i] = d_m[i] * b;
}
}
private static void transferGaussPixels(double[] src1, double[] src2, int[] dest, int bytes, int width) {
int i, j, k, b;
int bend = bytes * width;
double sum;
i = j = k = 0;
for (b = 0; b < bend; b++) {
sum = src1[i++] + src2[j++];
if (sum > 255)
sum = 255;
else if (sum < 0)
sum = 0;
dest[k++] = (int) sum;
}
}
/**
* 浮雕效果
*
* @param bmp
* @return
*/
public static Bitmap emboss(Bitmap bmp) {
int width = bmp.getWidth();
int height = bmp.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
int pixR = 0;
int pixG = 0;
int pixB = 0;
int pixColor = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int[] pixels = new int[width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
int pos = 0;
for (int i = 1, length = height - 1; i < length; i++) {
for (int k = 1, len = width - 1; k < len; k++) {
pos = i * width + k;
pixColor = pixels[pos];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
pixColor = pixels[pos + 1];
newR = Color.red(pixColor) - pixR + 127;
newG = Color.green(pixColor) - pixG + 127;
newB = Color.blue(pixColor) - pixB + 127;
newR = Math.min(255, Math.max(0, newR));
newG = Math.min(255, Math.max(0, newG));
newB = Math.min(255, Math.max(0, newB));
pixels[pos] = Color.argb(255, newR, newG, newB);
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
/**
* 图片锐化(拉普拉斯变换)
*
* @param bmp
* @return
*/
public static Bitmap sharpenImageAmeliorate(Bitmap bmp) {
if (ImageCache1.get("sharpenImageAmeliorate") != null) {
return ImageCache1.get("sharpenImageAmeliorate");
}
long start = System.currentTimeMillis();
// 拉普拉斯矩阵
int[] laplacian = new int[] { -1, -1, -1, -1, 9, -1, -1, -1, -1 };
int width = bmp.getWidth();
int height = bmp.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
int pixR = 0;
int pixG = 0;
int pixB = 0;
int pixColor = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int idx = 0;
float alpha = 0.3F;
int[] pixels = new int[width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
for (int i = 1, length = height - 1; i < length; i++) {
for (int k = 1, len = width - 1; k < len; k++) {
idx = 0;
for (int m = -1; m <= 1; m++) {
for (int n = -1; n <= 1; n++) {
pixColor = pixels[(i + n) * width + k + m];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
newR = newR + (int) (pixR * laplacian[idx] * alpha);
newG = newG + (int) (pixG * laplacian[idx] * alpha);
newB = newB + (int) (pixB * laplacian[idx] * alpha);
idx++;
}
}
newR = Math.min(255, Math.max(0, newR));
newG = Math.min(255, Math.max(0, newG));
newB = Math.min(255, Math.max(0, newB));
pixels[i * width + k] = Color.argb(255, newR, newG, newB);
newR = 0;
newG = 0;
newB = 0;
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
long end = System.currentTimeMillis();
Log.e("sharpenImageAmeliorate", "used time=" + (end - start));
ImageCache1.put("sharpenImageAmeliorate", bitmap);
return bitmap;
}
/**
* 底片效果
*
* @param bmp
* @return
*/
public static Bitmap film(Bitmap bmp) {
// RGBA的最大值
final int MAX_VALUE = 255;
int width = bmp.getWidth();
int height = bmp.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
int pixR = 0;
int pixG = 0;
int pixB = 0;
int pixColor = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int[] pixels = new int[width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
int pos = 0;
for (int i = 1, length = height - 1; i < length; i++) {
for (int k = 1, len = width - 1; k < len; k++) {
pos = i * width + k;
pixColor = pixels[pos];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
newR = MAX_VALUE - pixR;
newG = MAX_VALUE - pixG;
newB = MAX_VALUE - pixB;
newR = Math.min(MAX_VALUE, Math.max(0, newR));
newG = Math.min(MAX_VALUE, Math.max(0, newG));
newB = Math.min(MAX_VALUE, Math.max(0, newB));
pixels[pos] = Color.argb(MAX_VALUE, newR, newG, newB);
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
/**
* 光照效果
*
* @param bmp
* 光照中心x坐标
* @param centerX
* 光照中心要坐标
* @param centerY
* @return
*/
public static Bitmap sunshine(Bitmap bmp, int centerX, int centerY) {
final int width = bmp.getWidth();
final int height = bmp.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
int pixR = 0;
int pixG = 0;
int pixB = 0;
int pixColor = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int radius = Math.min(centerX, centerY);
final float strength = 150F; // 光照强度 100~150
int[] pixels = new int[width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
int pos = 0;
for (int i = 1, length = height - 1; i < length; i++) {
for (int k = 1, len = width - 1; k < len; k++) {
pos = i * width + k;
pixColor = pixels[pos];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
newR = pixR;
newG = pixG;
newB = pixB;
// 计算当前点到光照中心的距离,平面座标系中求两点之间的距离
int distance = (int) (Math.pow((centerY - i), 2) + Math.pow(centerX - k, 2));
if (distance < radius * radius) {
// 按照距离大小计算增加的光照值
int result = (int) (strength * (1.0 - Math.sqrt(distance) / radius));
newR = pixR + result;
newG = pixG + result;
newB = pixB + result;
}
newR = Math.min(255, Math.max(0, newR));
newG = Math.min(255, Math.max(0, newG));
newB = Math.min(255, Math.max(0, newB));
pixels[pos] = Color.argb(255, newR, newG, newB);
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
public static Bitmap toGrayscale(Bitmap bmpOriginal) {
int width, height;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bmpOriginal, 0, 0, paint);
return bmpGrayscale;
}
}
ImageToneActivity.javapackage imageUtil;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
/**
* 图片调色处理
*
*/
public class ToneLayer {
/**
* 饱和度标识
*/
public static final int FLAG_SATURATION = 0x0;
/**
* 亮度标识
*/
public static final int FLAG_LUM = 0x1;
/**
* 色相标识
*/
public static final int FLAG_HUE = 0x2;
/**
* 饱和度
*/
private TextView mSaturation;
private SeekBar mSaturationBar;
/**
* 色相
*/
private TextView mHue;
private SeekBar mHueBar;
/**
* 亮度
*/
private TextView mLum;
private SeekBar mLumBar;
private float mDensity;
private static final int TEXT_WIDTH = 50;
private LinearLayout mParent;
private ColorMatrix mLightnessMatrix;
private ColorMatrix mSaturationMatrix;
private ColorMatrix mHueMatrix;
private ColorMatrix mAllMatrix;
/**
* 亮度
*/
private float mLumValue = 1F;
/**
* 饱和度
*/
private float mSaturationValue = 0F;
/**
* 色相
*/
private float mHueValue = 0F;
/**
* SeekBar的中间值
*/
private static final int MIDDLE_VALUE = 127;
/**
* SeekBar的最大值
*/
private static final int MAX_VALUE = 255;
private ArrayList<SeekBar> mSeekBars = new ArrayList<SeekBar>();
public ToneLayer(Context context) {
init(context);
}
private void init(Context context) {
mDensity = context.getResources().getDisplayMetrics().density;
mSaturation = new TextView(context);
mSaturation.setText("饱和度 ");
mHue = new TextView(context);
mHue.setText("色相");
mLum = new TextView(context);
mLum.setText("亮度");
mSaturationBar = new SeekBar(context);
mHueBar = new SeekBar(context);
mLumBar = new SeekBar(context);
mSeekBars.add(mSaturationBar);
mSeekBars.add(mHueBar);
mSeekBars.add(mLumBar);
for (int i = 0, size = mSeekBars.size(); i < size; i++) {
SeekBar seekBar = mSeekBars.get(i);
seekBar.setMax(MAX_VALUE);
seekBar.setProgress(MIDDLE_VALUE);
seekBar.setTag(i);
}
LinearLayout saturation = new LinearLayout(context);
saturation.setOrientation(LinearLayout.HORIZONTAL);
saturation.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
LinearLayout.LayoutParams txtLayoutparams = new LinearLayout.LayoutParams((int) (TEXT_WIDTH * mDensity), LinearLayout.LayoutParams.MATCH_PARENT);
mSaturation.setGravity(Gravity.CENTER);
saturation.addView(mSaturation, txtLayoutparams);
LinearLayout.LayoutParams seekLayoutparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
saturation.addView(mSaturationBar, seekLayoutparams);
LinearLayout hue = new LinearLayout(context);
hue.setOrientation(LinearLayout.HORIZONTAL);
hue.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
mHue.setGravity(Gravity.CENTER);
hue.addView(mHue, txtLayoutparams);
hue.addView(mHueBar, seekLayoutparams);
LinearLayout lum = new LinearLayout(context);
lum.setOrientation(LinearLayout.HORIZONTAL);
lum.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
mLum.setGravity(Gravity.CENTER);
lum.addView(mLum, txtLayoutparams);
lum.addView(mLumBar, seekLayoutparams);
mParent = new LinearLayout(context);
mParent.setOrientation(LinearLayout.VERTICAL);
mParent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
mParent.addView(saturation);
mParent.addView(hue);
mParent.addView(lum);
}
public View getParentView() {
return mParent;
}
/**
* 设置饱和度值
* @param saturation
*/
public void setSaturation(int saturation) {
mSaturationValue = saturation * 1.0F / MIDDLE_VALUE;
}
/**
* 设置色相值
* @param hue
*/
public void setHue(int hue) {
mHueValue = hue * 1.0F / MIDDLE_VALUE;
}
/**
* 设置亮度值
* @param lum
*/
public void setLum(int lum) {
mLumValue = (lum - MIDDLE_VALUE) * 1.0F / MIDDLE_VALUE * 180;
}
public ArrayList<SeekBar> getSeekBars()
{
return mSeekBars;
}
/**
*
* @param flag
* 比特位0 表示是否改变色相,比位1表示是否改变饱和度,比特位2表示是否改变明亮度
*/
public Bitmap handleImage(Bitmap bm, int flag) {
Bitmap bmp = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(),
Bitmap.Config.ARGB_8888);
// 创建一个相同尺寸的可变的位图区,用于绘制调色后的图片
Canvas canvas = new Canvas(bmp); // 得到画笔对象
Paint paint = new Paint(); // 新建paint
paint.setAntiAlias(true); // 设置抗锯齿,也即是边缘做平滑处理
if (null == mAllMatrix) {
mAllMatrix = new ColorMatrix();
}
if (null == mLightnessMatrix) {
mLightnessMatrix = new ColorMatrix(); // 用于颜色变换的矩阵,android位图颜色变化处理主要是靠该对象完成
}
if (null == mSaturationMatrix) {
mSaturationMatrix = new ColorMatrix();
}
if (null == mHueMatrix) {
mHueMatrix = new ColorMatrix();
}
switch (flag) {
case FLAG_HUE: // 需要改变色相
mHueMatrix.reset();
mHueMatrix.setScale(mHueValue, mHueValue, mHueValue, 1); // 红、绿、蓝三分量按相同的比例,最后一个参数1表示透明度不做变化,此函数详细说明参考
// // android
// doc
break;
case FLAG_SATURATION: // 需要改变饱和度
// saturation 饱和度值,最小可设为0,此时对应的是灰度图(也就是俗话的“黑白图”),
// 为1表示饱和度不变,设置大于1,就显示过饱和
mSaturationMatrix.reset();
mSaturationMatrix.setSaturation(mSaturationValue);
break;
case FLAG_LUM: // 亮度
// hueColor就是色轮旋转的角度,正值表示顺时针旋转,负值表示逆时针旋转
mLightnessMatrix.reset(); // 设为默认值
mLightnessMatrix.setRotate(0, mLumValue); // 控制让红色区在色轮上旋转的角度
mLightnessMatrix.setRotate(1, mLumValue); // 控制让绿红色区在色轮上旋转的角度
mLightnessMatrix.setRotate(2, mLumValue); // 控制让蓝色区在色轮上旋转的角度
// 这里相当于改变的是全图的色相
break;
}
mAllMatrix.reset();
mAllMatrix.postConcat(mHueMatrix);
mAllMatrix.postConcat(mSaturationMatrix); // 效果叠加
mAllMatrix.postConcat(mLightnessMatrix); // 效果叠加
paint.setColorFilter(new ColorMatrixColorFilter(mAllMatrix));// 设置颜色变换效果
canvas.drawBitmap(bm, 0, 0, paint); // 将颜色变化后的图片输出到新创建的位图区
// 返回新的位图,也即调色处理后的图片
return bmp;
}
}
package com.Camera;
import imageUtil.ToneLayer;
import java.util.ArrayList;
import com.Filters.R;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
public class ImageToneActivity extends Activity implements OnSeekBarChangeListener {
private ToneLayer mToneLayer;
private ImageView mImageView;
private Bitmap mBitmap;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.handle_image);
init();
}
private void init()
{
mToneLayer = new ToneLayer(this);
byte[] buff = (byte[]) getIntent().getSerializableExtra("bitmap");;
mBitmap = BitmapFactory.decodeByteArray(buff, 0, buff.length);//重新编码出Bitmap对象
System.out.println(" mBitmap = " + mBitmap );
// mBitmap = ImageUtil.readBitMap(this, R.drawable.image);
mImageView = (ImageView) findViewById(R.id.img_view);
mImageView.setImageBitmap(mBitmap);
((LinearLayout) findViewById(R.id.tone_view)).addView(mToneLayer.getParentView());
ArrayList<SeekBar> seekBars = mToneLayer.getSeekBars();
for (int i = 0, size = seekBars.size(); i < size; i++)
{
seekBars.get(i).setOnSeekBarChangeListener(this);
}
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
int flag = (Integer) seekBar.getTag();
switch (flag)
{
case ToneLayer.FLAG_SATURATION:
mToneLayer.setSaturation(progress);
break;
case ToneLayer.FLAG_LUM:
mToneLayer.setLum(progress);
break;
case ToneLayer.FLAG_HUE:
mToneLayer.setHue(progress);
break;
}
mImageView.setImageBitmap(mToneLayer.handleImage(mBitmap, flag));
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
涉及到的xml布局文件:
main.xml
<?xml version="1.0" encoding="utf-8"?>item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/white"
android:orientation="vertical" >
<com.cameraView.CameraView
android:id="@+id/mSurfaceView1"
android:layout_width="fill_parent"
android:layout_height="240dp"
android:visibility="visible" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="40dp"
android:orientation="horizontal" >
<Button
android:id="@+id/myButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/str_button1" />
<Button
android:id="@+id/myButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/str_button2" />
<Button
android:id="@+id/myButton3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/str_take_picture" />
<Spinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
/>
</LinearLayout>
<ImageView
android:id="@+id/myImageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:scaleType="fitXY"/>
</LinearLayout>
handle_message.xml<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textViewForItem"
android:layout_width="fill_parent"
android:layout_height="30dp"
android:textColor="#566E95"
android:gravity="center"
android:textSize="12sp"
/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/img_view"
android:layout_gravity="center"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/tone_view"
/>
</LinearLayout>
</ScrollView>
strings.xml
<?xml version="1.0" encoding="utf-8"?>清单文件menifest.xml
<resources>
<string name="hello">Hello World, eoe.demo</string>
<string name="app_name">相机测试</string>
<string name="str_button1">Preview</string>
<string name="str_button2">关闭相机</string>
<string name="str_take_picture">拍照</string>
<string name="str_err_nosd">※未发信安装SD存储卡※</string>
</resources>
效果图:<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.Filters"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name="com.Camera.CameraActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.Camera.ImageToneActivity"></activity>
</application>
<uses-permission android:name="android.permission.CAMERA" />
<!-- 对外部存储设备的写入权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 对外部文件的写入和删除权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-feature android:name="android.hardware.camera.autofocus" />
</manifest>

