Android11_图片处理

安卓多媒体编程

1,计算机图形的表示方式方法

1.1

①像素点形式(单色位图),一个像素点相当于1*1个像素,8个像素点就是8个0011占据一个byte的位置,200*200=40000 40000/8 = 5000byte字节

②24位位图,一个像素点有24位(2的24次方)来表示颜色 ,3个byte.40000*24/8 = 120000byte字节

③256位图,一个像素点占256色,为(2的8次方),一个byte.40000byte就可以表示.

1.2

矢量图形:储存的是指令,而不是像素点

位图的缺陷:占据体积比较大

常见位图格式:JPEG,PNG,BMP,前面两种通过图片压缩算法减少储存空间(即相同的颜色进行压缩,因为人眼无法识别这些细微差别)

2,加载图片到内存

①通过BitmapFactory.docodeFile(path)解码图片到内存上

BitmapFactory.docodeXX,还可以转换流,文件(默认都是32位的位图,a(透明度)rgb(颜色))

②如果加载过大的图片,会出现OOM:Out of MemoryError 内存不足异常

虽然一个图片看起来不大,但是通过BitMapFactory加载出来的图片,是跟图片的分辨率有关,一个像素就需要4个byte去表示

创建模拟器的时候有一个选项VM heep一个应用程序能申请的最大内存空间,默认16MB

2.2 加载大图片到手机中

对图片进行缩放:BitMapFactory.docodeFIle(path,opts(可以是空,也可以压缩));

Option opts = new Option();

opts.inSampleSize=xx,设置采样率,如果设置的值大于1,就会重新采样原图,返回一个小一点的图片用来节约内存,如果等于4,就把原来的图片宽高缩小为原来四分之一,相当于总像素个数占原来的十六分之一.

一般的计算方式:根据当前手机的分辨率进行计算

①获取手机的宽高信息,和图片的分辨率

②获取图片的分辨率(宽高信息)

ExifInterface exif =new xxxx(filepath);//得到照片的头信息(拍摄信息,时间,地点,类型)

exif.getAttribute(ExifInterface.XXXX);//有一些常量可以获取信息.

exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH,默认值(0))

//有的文件是通过图片软件生成的,或画出来的,没有头信息

这时候就要采用另一种做法

Option opt1 = new Option();

Opt1.inJustDecodeBounds = true;//设置为false就没有把bitmap加载到内存

//不把图片加载到内存,而是先获取宽高,再进行缩放比

//注意这里需要先让程序解析一次

BitmapFactory.decodeFile(img.getAbsolutePath(), opts);

Opt1.outHeight; opt1.outWidth;

//设置为false之后再解析一次

BitmapFactory.decodeFile(img.getAbsolutePath(), opts);

③获取手机屏幕的宽高

//获取屏幕管理器

WindowManager wm = getSystemService(WINDOW_SERVICE);

wm.getDefultDisplay().getXXX()//宽高,(推荐使用getSize(Point outsize)大小)

Point outsize = new Point();//api13开始使用的

④计算缩放比,按大一点的缩放比比较好一些,按公司的业务需求来

3,图形的缩放

需求,对图片进行缩放并显示在页面上

①获取原图,

BitMap srcMap= BitMapFactory.decodeFile(path);

把原图加载进内存(一般都不对原图进行处理,而是处理原图在内存中的拷贝)创建原图在内存中的拷贝:

//创建一个等大小,类型的空白图片

copyedBitmap = BitMap.createBitMap(宽,高,图形的类型)//返回一个可以编辑的bmp图片,指定宽高和类型,一般在安卓里指定32位位图,获取原图的类型,srcMap.getConfig();

//创建一个画板,传入创建的空白图片

Canvas canvas = new Canvas(copyedBitmap);

//创建一个画笔

Paint paint new Paint();

//设置画笔的颜色

paint.setColor(Color.Black);

//开始画画

Matrix matrix = new Matrix();//按照1:1的比例作画

matrix.setScale(sx(0.2f),sy)//水平,竖直方向的缩放比,单位f

canvas.drawBitMap(原图,变化矩阵,paint);

//把拷贝出来的图片显示在界面上,

setImageBitMap()会自动处理图片适应屏幕

3.2

3.2.1图片的平移

matrix.setTranslate(dx,dy);//水平,竖直方向的偏移量,移动图片的像素点(会丢失图片内容)

3.2.2图片的旋转

matrix.setRotate(旋转的角度);以左上角为原点进行旋转

matrix.setRotate(旋转的角度,px,py)//以指定的坐标旋转(如果想让它以中心旋转,坐标设置宽高的二分之一)

3.2.3镜面效果,本质上是X坐标轴取反,Y轴不变,然后平移过来(或者覆盖原有图片)

matrix.setScale(-1,1)//宽度变成原来的负值,这时候图片会超出屏幕,需要移动回来

matrix.setTranslate(srcbitmap.getWidth(),0)//移动对应图片的宽度

setXXX都是设置的方法,不能同时生效,后面的会覆盖前面的

如果希望后面的方法实现,需要使用postTranslate(XXXXX)方法,在上一次修改之后的基础上进行变化.

3.2.4倒影效果,上下翻转(Y轴取反,X轴不变)(跟旋转180度效果不是一样的)

4,练习,随手涂鸦

4.1 ui布局

第一排,工具栏,供用户选择画笔的颜色,并显示对应颜色的区块,

画笔的粗细(用户输入,或通过SeekBar设置也可以)

setMax(最大值),默认值progress(5,其它也可以)

剩余区域绘画区域

4.2 在MainActivity中,找到这些控件,设置对应的点击事件

①创建一个画笔

Paint paint = new Paint();

paint.setColor( 指定画笔的颜色);

paint.setStorkeWidth(width);//设置画笔的宽度

②SeekBar相关

SeekBar.setOnSeekBarChangeListener();//拖动变化监听器

seekbar.getProgress()//获取当前拖动的状态

4.3①作画位置实际是在一个ImageView中作画

要提前指定ImageView的宽高,因为一旦被加载就固定了

//给imageView注册一个触摸事件

iv.setOnTouchListener(new OnTouchListener(){

//当被触摸的时候调用

public boolean onTouch(View v,MotionEvent event){

//通过按下的动作判断(按下触摸的时候,保持拖动的时候,松开触摸的时候)

switch(event.getAction){

case: MotionEvent.Action_MOVE

每移动一个像素点调用一次

break;

case: MotionEvent.Action_DOWN

break;

case: MotionEvent.Action_UP

break;

}

//返回值默认返回一个false,代表:事件没有处理完毕,要等待事件处理完毕.

//如果为flase移动和松开手指的事件就不会执行,一直在等待按下事件结束.

//true:代表事件已经处理完毕,没有处理完就不会触发松开和拖动事件

//

return true;

}

});

②需要一个可以被修改的图片

BitMap alertMap ;//需要的图片

Canvas canvas;//定义画板,画笔已经有了

alertMap = BitMap.createBitMap(320,320,BitMap.ARGB_8888);//8888高质量的位图.

Canvas = new Canvas(alertMap);

③在控件触摸事件方法中

定义横纵坐标int x int y .

在按下的位置,获取坐标

在拖动的时候,获取坐标

canvas.drawLine(sx,sy,nx,ny,画笔);//执行完这个方法后就画出了一条线

Iv.setImageBitMap(alertMap)//把线显示在控件上

//但是这样做,会出现开始坐标固定的情况下画出一个不想要的图形,需要重新初始化手指在屏幕上的坐标(实际上一条线是由无数个短线拼接,也就是两个像素点之间的拼接,而不改变初始位置,就会像画了个大圆饼)

4.4 其它细节问题

(0)拿取控件的宽高拿不到,因为控件的绘制是跟Activity异步的,就算执行了onCreate,onStart,onResume()都拿不到.

(1)要通过view绘制成功的监听获取,但在监听的时候如果绘制的view发生改变了,就会重新绘制一次,所以可以在获取到一次数据之后把监听注销掉

(2)获取绘制监听事件iv.getViewTreeObs

(3)LinearLayout绘制顺序,先绘制最外层的Liner 再按设置的顺序,从上至下绘制,树形结构的绘制,开发中不建议布局LinearLayOut的嵌套,因为比较消耗时间

//注册View绘制监听事件

iv_show.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

//注销监听

iv_show.getViewTreeObserver().removeGlobalOnLayoutListener(this);

}

});

①在Activity中,onCreateOptionMenu(Menu menu)//创建一个选项菜单调用的方法

//本质上就是一个在底部出现的ListView视图,里面的控件都是item

判断用户点击的是哪一个条目menu.getItemId();

//保存图片,把BitMap转换为流,可以保存在内存中,内存输出流

alertBitMap.compress(format(保存的格式),quality(图片的质量1-100),stream输出流);

记得关流

//这样输出的图片背景颜色是黑色,因为BitMap默认都是黑色的,所以创建好了画板之后

canvas.drawColor(Color.WHITE);//画一个白色的背景

②在图库应用中找不到画的图片,因为系统图库是不知道这个图片被添加了,只有在开机或SD卡拔重新插入添加之后才会扫描添加

这时候就要告诉图库,图片被添加了

通过模拟SD卡被插入的广播,告诉图库需要重新扫描一次 4.4版本之后就不能用了

Intent intent = new Intent();//创建意图

intent.setAction(Intent.ACTION.MEDIA_MOUNTED);//设置动作

intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));//设置文件

sendBroadCast(intent);//发送广播

5.撕衣服的小应用

①对图片进行缩放处理,代码拷贝图片,不对原图进行操作

本质上是两张图片相互覆盖,如果在图片上滑动,就把滑动的区域设置为透明.

//不要修改原图,先创建一个原图的拷贝

创建空白图片,创建画板,创建画笔,画一个跟原图一样的图片

②设置触摸事件

onTouch方法返回值记得设置为true

触摸的点设置为透明

设置按下点为透明,alertBitmap.setPixel(x,y,Color.TRANSPARENT)//设置为透明的

然后重新设置图片lv.setImageBitMap(图片)即可

③撕衣服用户体验差,需要提高撕衣服的范围

//通过 for循环把对应坐标点的周围的点也设置为透明

这样每次的透明块是一个矩形块,不好看,要每次的透明块为一个圆形更好

由此图可知,需要一个圆形,就代表这个像素点的坐标到圆心的距离小于等于3(通过勾股定理可以算出)

Math.sqrt()开平方

④如果超出图片范围就崩溃.

处理方式:把异常捕获进来,然后超出图片就不会出异常(尴尬)

⑤getX()和getrawX()的区别raw(未经处理的)

getrawX()距离屏幕左边的距离.getrawY()距离屏幕上边的距离

getX()距离当前控件的左边距离,getY()距离当前控件上边的距离

6,图片颜色的处理

图像颜色的处理:把每个像素点的颜色按照一定的规则进行变化,就会出现新的效果

颜色矩阵模板代码:

ColorMatrix cm = new ColocrMartix();//颜色矩阵

Cm.set(new float[]{

1*result(变化比例),0,0,0,0, //red

0,1,0,0,0, //green

0,0,1,0,0, //blue

0,0,0,1,0 //透明度

});

paint.setColorFilter(new ColorMatrixColorFilter(cm));//设置颜色过滤器

然后根据拖动条改变对应的颜色即可

posted on 2016-06-03 22:28 抓根宝 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/adventurer/p/5557786.html

Android11_图片处理相关推荐

  1. Python+OpenCV 图像处理系列(1)— Ubuntu OpenCV安装、图片加载、显示和保存

    Ubuntu 16.04 下安装 Opencv sudo apt-get install libopencv-dev sudo apt-get install python-opencv 或者使用 p ...

  2. FastAI 课程学习笔记 lesson 1:宠物图片分类

    文章目录 代码解析 神奇的"%" 导入fastAI 库 下载解压数据集 untar_data 获取帮助文档 help() ? ?? doc 设置路径 get_image_files ...

  3. 1 用python进行OpenCV实战之用OpenCV3实现图片载入、显示和储存

    code 将下面文档存为load_display_save.py #-*- coding:utf-8 -*- from __future__ import print_function #1 impo ...

  4. java 16进制与图片互转

    十六进制转成图片 /*** 十六进制转成图片* @author Administrator**/public static void saveToImgFile(String src,String o ...

  5. ttf,woff2字体转化为png图片,python读取图片

    20210326 乱码转换的时候 是同一套unicode编码 但是在不同的字体库中对应的字不同 20210324 https://jingyan.baidu.com/article/e73e26c0c ...

  6. LeetCode简单题之图片平滑器

    题目 包含整数的二维矩阵 M 表示一个图片的灰度.你需要设计一个平滑器来让每一个单元的灰度成为平均灰度 (向下舍入) ,平均灰度的计算是周围的8个单元和它本身的值求平均,如果周围的单元格不足八个,则尽 ...

  7. Typora+PicGo图床配置(本地图片-->网络url~博客必备)

    前段时间搭了一个hexo博客,但是发现了一个很大的问题,在Typora里编辑你的博文的时候,插入的图片都是一些本地图片,然后部署的时候根本不能加载这些图片~~ 其中一个解决方法就是通过一些平台,像知乎 ...

  8. OFRecord 图片文件制数据集

    OFRecord 图片文件制数据集 在 OFRecord 数据格式 和 加载与准备 OFRecord 数据集 中,分别学习了 OFRecord 数据格式,以及如何将其它数据集转为 OFRecord 数 ...

  9. CVPR2020论文解读:CNN合成的图片鉴别

    CVPR2020论文解读:CNN合成的图片鉴别 <CNN-generated images are surprisingly easy to spot- for now> 论文链接:htt ...

  10. php将图片链接转换为base64编码文件流

    /** * 图片链接转换为 base64 文件流 * @param $imgUrl * @return string */ function img_url_to_base64($imgUrl) {$ ...

最新文章

  1. java操作es聚合操作并显示其他字段_java使用elasticsearch分组进行聚合查询过程解析...
  2. RSA加密和DH加密
  3. IOS UISearchDisplayController 点击搜索出现黑条问题解决方案
  4. 1131: 零起点学算法38——求阶乘和
  5. MySQL基于ROW格式的数据恢复
  6. Caffe —— Deep learning in Practice 深度学习实践
  7. html桌面图标样式,如何更改图标样式,换桌面图标的方法
  8. idea junit 测试看不到控制台报错信息_高手都这么给 Spring MVC 做单元测试!
  9. 作者:王学志(1979-),男,中国科学院计算机网络信息中心副研究员。
  10. Qt应用程序只运行一个实例
  11. 新增5大运维特性!华为云DAS服务高效运维有妙招
  12. adb命令连接模拟器,could not read ok from ADB Server
  13. Android下基于UVC的UsbCam的开发
  14. LCA(最近公共子序列)
  15. 联想计计算机电源管理,联想电源管理软件energy manag
  16. ideaIU-2020.3.2安装教程以及导入第一个spring boot项目运行和环境配置教程
  17. Tensorflow2.0---SSD网络原理及代码解析(一)
  18. Linux操作系统笔记(基本命令+环境安装项目部署+Shell编程)
  19. cad快看_星期日来啦!分享5个珍藏已久的电影网站,各种大片免费看
  20. 我的世界1.16.1java模组怎么加,我的世界1.16(minecraft1.16)全新模组推荐

热门文章

  1. Java多线程之FutureTask
  2. AngularJs HelloWorld
  3. 你确定你真的懂Nginx与PHP的交互?
  4. 阿里云宝塔Linux服务器管理面版初始化地址不能登入(原创)
  5. shell字符串的截取的问题
  6. .text urlRewrite介绍
  7. Android开发之软键盘遮盖EditText
  8. 打印九九乘法表算法-java
  9. [JNI]开发之旅 (3)jni域描述符说明
  10. BZOJ1070[SCOI2007] 修车