图片
来源:互联网 发布:沙钢网络培训平台 编辑:程序博客网 时间:2024/05/16 01:43
Gallery是系统自带的相册,与之对应的Activity类是GalleryPicker。
相册中图片列表对应一个Activity类ImageGallery。
所有可以使用startActivityForResult方法跳转到该Activity,点击一张图片后获取返回数据。系统会返回图片的Uri。
而自定义ImageView可以使用方法setImageURI(uri)就可以展示指定图片了。
2.获取位图bitmap
1)从项目资源获取
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.a);
2)从网络流获取
// 获取输入流
InputStream in = response.getEntity().getContent();
// 将输入流转成Bitmap
Bitmap bitmap = BitmapFactory.decodeStream(in);
3)根据颜色矩阵创建图片
Bitmap bitmap = Bitmap.createBitmap(int[] colors, width, heigth, Config config);
//最后一个参数: Config.ARGB_8888或者其他
4)从sd卡中加载图片
Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/a.jpg");
3.加载大图片内存溢出OOM
2M的图片加载到内存需要30M内存
1) 一般加载大图片到内存只加载原来的n分之一,比如八分之一
代码:
BitmapFactory.Options opts = new BitmapFactory.Options(); // 设置图片为原来的八分之一 opts.inSampleSize = 8; Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/big.jpg", opts); iv.setImageBitmap(bitmap);
2) 根据当前屏幕分辨率的大小,按比例加载图片
代码:
BitmapFactory.Options opts = new BitmapFactory.Options();// 设置不获取图片本身,只获取图片的属性opts.inJustDecodeBounds = true;BitmapFactory.decodeFile("/mnt/sdcard/mm.jpg", opts);// 获取图片的宽高int width = opts.outWidth;int height = opts.outHeight;System.out.println("图片的宽和高:" + width + " --- " + height);// 获取屏幕的宽高Display display = getWindowManager().getDefaultDisplay();int sw = display.getWidth();int sh = display.getHeight();System.out.println("屏幕的宽和高:" + sw + " --- " + sh);// 得到图片宽高和屏幕宽高的比例// ceil -- 向上取整int widthRatio = (int) Math.ceil(width / (float) sw);int heightRatio = (int) Math.ceil(height / (float) sh);Log.v("WIDTHRATIO", widthRatio + "");Log.v("HEIGHTRATIO", heightRatio + "");// 如果图片的宽高大于屏幕宽高,那么按宽高变化大的进行缩放if (widthRatio > 1 && heightRatio > 1) {// 将比例大的设置为缩放因子opts.inSampleSize = widthRatio > heightRatio ? widthRatio: heightRatio;}// 重新设置opts为获取图片opts.inJustDecodeBounds = false;// 加载图片Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/mm.jpg", opts);iv.setImageBitmap(bitmap);
4.图片涂鸦
核心代码:
1) ImageView.setOnTouchListener(listener); 给ImageView设置触摸事件,注意监听器的onTouch方法返回值是true,表示消费掉事件,不再传递。在onTouch方法中,进行涂鸦绘制。
iv.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// 绘制开始位置int startX = 0;int startY = 0;switch (event.getAction()) {// 按下case MotionEvent.ACTION_DOWN:// 记录开始位置startX = (int) event.getX();startY = (int) event.getY();break;// 移动case MotionEvent.ACTION_MOVE:// 移动每一点,记录结束位置int stopX = (int) event.getX();int stopY = (int) event.getY();// 根据其实位置,画线canvas.drawLine(startX, startY, stopX, stopY, paint);// 将线绘制到新图片上iv.setImageBitmap(bit);// 将结束位置设置为新的起始位置startX = stopX;startY = stopY;break;// 抬起case MotionEvent.ACTION_UP:break;default:break;}// 返回true,消费了本次事件,不再向下传递return true;}});
2) 创建Canvas,传入的Bitmap一定是新创建的而不是加载的图片,即不能再原图片上绘制。
//加载图片 Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/mm.jpg", opts); // 根据原图重新创建一张图片 Bitmap bit = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),bitmap.getConfig()); //创建画布,将新图片作为参数传递到画布 //一定要注意不要使用原图,否则抛出异常 Canvas canvas = new Canvas(bit); //绘制新图片 canvas.drawBitmap(bitmap, new Matrix(), paint);
总代码:
public class MainActivity extends Activity {private ImageView iv;// 加载的原图private Bitmap bitmap;// 根据原图绘制的新图private Bitmap bit;private Canvas canvas;private Paint paint;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);iv = (ImageView) findViewById(R.id.iv);// 加载图片bitmap = BitmapFactory.decodeFile("/mnt/sdcard/mm.jpg");// 画布与画笔// 根据原图重新创建一张图片bit = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),bitmap.getConfig());// 创建画布,将新图片作为参数传递到画布// 一定要注意不要使用原图,否则抛出异常canvas = new Canvas(bit);// 画笔paint = new Paint();// 把原图内容绘制到新图片canvas.drawBitmap(bitmap, new Matrix(), paint);// 将新图片设置到ImageViewiv.setImageBitmap(bit);// 设置监听iv.setOnTouchListener(new OnTouchListener() {// 绘制开始位置int startX;int startY;@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {// 按下case MotionEvent.ACTION_DOWN:// 记录开始位置startX = (int) event.getX();startY = (int) event.getY();break;// 移动case MotionEvent.ACTION_MOVE:// 移动每一点,记录结束位置int stopX = (int) event.getX();int stopY = (int) event.getY();// 根据其实位置,画线canvas.drawLine(startX, startY, stopX, stopY, paint);// 将线绘制到新图片上iv.setImageBitmap(bit);// 将结束位置设置为新的起始位置startX = stopX;startY = stopY;break;// 抬起case MotionEvent.ACTION_UP:break;default:break;}// 返回true,消费了本次事件,不再向下传递return true;}});}}
5.图片加水印并保存
加水印:
核心代码:canvas.drawText(String text, float x, float y, Paint paint);
参数:内容,起始x,起始y,画笔。
注意:同样需要根据原图新创建一张图片。
保存:
核心代码:bitmap.compress (Bitmap.CompressFormat format, int quality, OutputStream stream)
6. 改变图片的rgba
安卓把颜色通过4*5的颜色矩阵进行处理。
核心类:ColorFilter ColorMatirx
核心代码:paint.setColorFilter(filter);
开发时使用其子类 --- ColorMatrixColorFilter
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(ColorMatrix matrix);
创建ColorMatrixColorFilter实例时需要一个参数:ColorMatrix
ColorMatrix matrix = new ColorMatrix();
//设置一个4*5数组
matrix.set(new float[]{
1,0,0,0,0, //r
0,1,0,0,0, //g
0,0,1,0,0, //b
0,0,0,1,0 //a
});
代码:
// 加载图片Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/mm.jpg");// 根据原图创建新图片Bitmap bm = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),bitmap.getConfig());Canvas canvas = new Canvas(bm);Paint paint = new Paint();//改变图片的rgbaColorMatrix matrix = new ColorMatrix();matrix.set(new float[]{1,0,0,0,0, //r0,1,0,0,0, //g0,0,1,0,0, //b0,0,0,0.3f,0 //a});ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);//rgba核心代码 --- 设置画笔的颜色过滤器paint.setColorFilter(filter);// 绘制新图片canvas.drawBitmap(bitmap, new Matrix(), paint);iv.setImageBitmap(bm);
public class MainActivity extends Activity {private SeekBar sbR;private SeekBar sbG;private SeekBar sbB;private SeekBar sbA;private ImageView iv;private Bitmap bitmap;private Bitmap bm;private Canvas canvas;private Paint paint;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sbR = (SeekBar) findViewById(R.id.sb_r);sbG = (SeekBar) findViewById(R.id.sb_g);sbB = (SeekBar) findViewById(R.id.sb_b);sbA = (SeekBar) findViewById(R.id.sb_a);iv = (ImageView) findViewById(R.id.iv);// 加载图片bitmap = BitmapFactory.decodeFile("/mnt/sdcard/mm.jpg");bm = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),bitmap.getConfig());canvas = new Canvas(bm);paint = new Paint();// 绘制新图片canvas.drawBitmap(bitmap, new Matrix(), paint);iv.setImageBitmap(bm);// 改变图片红色显示sbR.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {// 根据progress计算比例float rate = (float) (255 - progress) / 255;ColorMatrix matrix = new ColorMatrix();matrix.set(new float[] { rate, 0, 0, 0, 0, // r0, 1, 0, 0, 0, // g0, 0, 1, 0, 0, // b0, 0, 0, 1, 0 // a});ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);// rgba核心代码 --- 设置画笔的颜色过滤器paint.setColorFilter(filter);// 绘制新图片canvas.drawBitmap(bitmap, new Matrix(), paint);iv.setImageBitmap(bm);}});// 改变图片绿色显示sbG.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {// 根据progress计算比例float rate = (float) (255 - progress) / 255;ColorMatrix matrix = new ColorMatrix();matrix.set(new float[] { 1, 0, 0, 0, 0, // r0, rate, 0, 0, 0, // g0, 0, 1, 0, 0, // b0, 0, 0, 1, 0 // a});ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);// rgba核心代码 --- 设置画笔的颜色过滤器paint.setColorFilter(filter);// 绘制新图片canvas.drawBitmap(bitmap, new Matrix(), paint);iv.setImageBitmap(bm);}});// 改变图片蓝色显示sbB.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {// 根据progress计算比例float rate = (float) (255 - progress) / 255;ColorMatrix matrix = new ColorMatrix();matrix.set(new float[] { 1, 0, 0, 0, 0, // r0, 1, 0, 0, 0, // g0, 0, rate, 0, 0, // b0, 0, 0, 1, 0 // a});ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);// rgba核心代码 --- 设置画笔的颜色过滤器paint.setColorFilter(filter);// 绘制新图片canvas.drawBitmap(bitmap, new Matrix(), paint);iv.setImageBitmap(bm);}});// 改变图片透明度sbA.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {// 根据progress计算比例float rate = (float) (255 - progress) / 255;ColorMatrix matrix = new ColorMatrix();matrix.set(new float[] { 1, 0, 0, 0, 0, // r0, 1, 0, 0, 0, // g0, 0, 1, 0, 0, // b0, 0, 0, rate, 0 // a});ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);// rgba核心代码 --- 设置画笔的颜色过滤器paint.setColorFilter(filter);// 绘制新图片canvas.drawBitmap(bitmap, new Matrix(), paint);iv.setImageBitmap(bm);}});}}
7.设置图片为黑白效果
核心代码:
paint.setColorFilter(filter);
//颜色矩阵 --- ColorMatrix
matrix.setSaturation(0);
总代码:
bitmap = BitmapFactory.decodeFile("/mnt/sdcard/mm.jpg");// 画布与画笔// 根据原图重新创建一张图片bit = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),bitmap.getConfig());// 创建画布,将新图片作为参数传递到画布// 一定要注意不要使用原图,否则抛出异常canvas = new Canvas(bit);// 画笔paint = new Paint();// 设置成黑白效果ColorMatrix matrix = new ColorMatrix();// 核心代码matrix.setSaturation(0);ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);paint.setColorFilter(filter);// 把原图内容绘制到新图片canvas.drawBitmap(bitmap, new Matrix(), paint);// 将新图片设置到ImageViewiv.setImageBitmap(bit);
8.图片的缩放
安卓中使用3*3的矩阵对图片进行处理。
核心类:Matrix
核心代码:matrix.setScale(float sx, float sy)
例:
// 使用矩阵进行缩放
Matrix matrix = new Matrix();
// 宽为原图2倍,高为原图2分之1
matrix.setScale(2.0f, 0.5f);
canvas.drawBitmap(bitmap, matrix, paint);
代码:
布局xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/iv1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:id="@+id/iv2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout></ScrollView>
MainActivity
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ImageView iv1 = (ImageView) findViewById(R.id.iv1);ImageView iv2 = (ImageView) findViewById(R.id.iv2);// 加载图片Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/mm.jpg");// 根据原图片创建新图片// 宽是原图2倍,高是原图2分之1Bitmap bm = Bitmap.createBitmap(bitmap.getWidth() * 2,bitmap.getHeight() / 2, bitmap.getConfig());Canvas canvas = new Canvas(bm);// 使用矩阵进行缩放Matrix matrix = new Matrix();// 宽为原图2倍,高为原图2分之1matrix.setScale(2.0f, 0.5f);Paint paint = new Paint();canvas.drawBitmap(bitmap, matrix, paint);iv1.setImageBitmap(bitmap);iv2.setImageBitmap(bm);}}
9.图片的旋转
核心类:Matrix
核心方法:
1)
matrix.setRotate(float degrees)
matrix.setRotate(float degrees, float px, float py)
围绕点px, py 旋转 degrees度, 如果没设置坐标,默认以0,0点旋转.
例:
matrix.setRotate(90, 180, 120);
2)
matrix.postRotate(float degrees)
matrix.postRotate(float degrees, float px, float py)
10.图片平移
核心类:Matrix
核心方法:matrix.setTranslate(float dx, float dy)
matrix.postTranslate(float dx, float dy)
例:matrix.setTranslate(100, 100) //100px
11.镜面效果 --- 翻转
翻转实际使用图片的缩放,即matrix.setScale();
镜面效果原理是先将图片沿y轴线翻转,然后再平移回去。
核心代码:
// 先将图片沿y轴翻转
matrix.setScale(-1f, 1f);
// 再将图片平移回来
matrix.postTranslate(bitmap.getWidth(), 0);
12.倒影效果 --- 将y坐标沿x轴翻转
倒影效果原理是先将图片沿x轴线翻转,然后再平移回去。
核心代码:
// 先将图片沿x轴翻转
matrix.setScale(1f, -1f);
// 再将图片平移回来
matrix.postTranslate(0, bitmap.getHeight());
// 加载图片Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/mm.jpg");// 根据原图片创建新图片Bitmap bm = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),bitmap.getConfig());Canvas canvas = new Canvas(bm);// 使用矩阵实现镜面效果Matrix matrix = new Matrix();// 1.缩放// matrix.setScale(2.0f, 0.5f);// 2.旋转// matrix.setRotate(45, 200, 180);// 3.平移// matrix.setTranslate(100, 100);// 4.镜面效果/*// 先将图片沿y轴翻转matrix.setScale(-1f, 1f);// 再将图片平移回来matrix.postTranslate(bitmap.getWidth(), 0);*/// 5.倒影效果// 先将图片沿x轴翻转matrix.setScale(1f, -1f);// 再将图片平移回来matrix.postTranslate(0, bitmap.getHeight());Paint paint = new Paint();canvas.drawBitmap(bitmap, matrix, paint);iv1.setImageBitmap(bitmap);iv2.setImageBitmap(bm);
13.Matrix的setXxx()方法和postXxx()方法的区别
Matrix中带有pre, post的函数需要考虑先后顺序
其实Matrix方法中的setXxx()方法会先清除该矩阵,即设为单位矩阵。之后设置其他操作的,所以是不能叠加各种效果在一起。
所以,如果是想多种效果同时使用的话,用postRotate(), postTranslate()等类似的矩阵变换方法。
14.小结
1) 与图片内容相关:比如涂鸦、水印,使用Canvas --- drawXXX(...) : canvas.drawLine(...) canvas.drawText(...)
2) 与图片颜色相关:rgba,使用Paint/ColorFilter/ColorMatrix
3) 与图片位置相关:平移、缩放、旋转等,使用Matrix
15.获得图片的像素矩阵
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.a);
//像素数组
int[] pixels = new int[bitmap.getWidth() * bitmap.getHeigth()];
bitmap.getPixels(pixels, offset, stride, x, y, width, height);
- 图片
- 图片
- 图片
- 图片
- 图片
- 图片
- 图片
- 图片
- 图片
- 图片
- 图片
- 图片
- 图片
- 图片
- 图片
- 图片
- 图片
- 图片
- 对Socket CAN的理解(1)——【CAN总线原理】 .
- memcopy, memset, strcopy, strncpy用法总结
- Metasploitable2 - tcp port 3306 - mysql
- 所有的排序、查找算法
- ACM算法学习之贪心算法---字典序POJ3617(算法思想篇)
- 图片
- 互斥量和信号量的区别
- Linux 路由 学习笔记 之一 相关的数据结构
- 什么时候该采用结对编程
- SEAndroid安全机制对Binder IPC的保护分析
- Flex中的DataGrid报错(一)
- 设置VS2010和IE8 调试ATL控件
- PS高斯模糊后变清晰(智能滤镜、蒙版)的使用
- C语言字符串操作