19_Android中图片处理原理篇,关于人脸识别网站,图片加载到内存,图片缩放,图片翻转倒置,网上撕衣服游戏案例编写
1 加载图片到内存
(1).数码相机照片特别是大于3m以上的,内存吃不消,会报OutOfMemoryError,若是想只显示原图片的1/8,可以通过BitmapFactory.Options来实现,具体代码如下:
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inSampleSize = 8; Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions); imv.setImageBitmap(bmp); 如果图片太大,会出现的以下的问题: |
2 根据当前屏幕分辨率的大小,加载图片 Display currentDisplay = getWindowManager().getDefaultDisplay(); int dw = currentDisplay.getWidth(); int dh = currentDisplay.getHeight(); BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions); //通过下面的代码计算缩放比,那个方向的缩放比大,就按照这把方向的缩放比来缩放。 int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)dh); int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)dw); Log.v("HEIGHTRATIO",""+heightRatio); Log.v("WIDTHRATIO",""+widthRatio); //判断是否要进行缩放 if (heightRatio > 1 && widthRatio > 1) { if (heightRatio > widthRatio) { //高度变化大,按高度缩放 bmpFactoryOptions.inSampleSize = heightRatio; } else { // 宽度变化大,按宽度缩放 bmpFactoryOptions.inSampleSize = widthRatio; } } bmpFactoryOptions.inJustDecodeBounds = false; bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions); |
3 获取Exif图片信息 //从文件获取exif信息 ExifInterface ei = new ExifInterface(imageFilePath); String imageDescription = ei.getAttribute("ImageDescription"); if (imageDescription != null) { Log.v("EXIF", imageDescription); } //把exif信息写到文件: ExifInterface ei = new ExifInterface(imageFilePath); ei.setAttribute("ImageDescription","Something New"); |
4 从gallery获取一个图片 Intent intent = new Intent(Intent.ACTION_PICK); intent.setType(“image/*”); intent.getData() 获取image的uri Bitmap bmp = BitmapFactory.decodeStream(getContentResolver(). openInputStream(imageFileUri), null, bmpFactoryOptions); |
5 创建bitmap拷贝 Bitmap bmp = BitmapFactory.decodeStream(getContentResolver(). openInputStream(imageFileUri), null, bmpFactoryOptions); Bitmap alteredBitmap = Bitmap.createBitmap(bmp.getWidth(),bmp.getHeight(), bmp.getConfig()); Canvas canvas = new Canvas(alteredBitmap); Paint paint = new Paint(); canvas.drawBitmap(bmp, 0, 0, paint); |
6 图形缩放 Matrix matrix = new Matrix(); matrix.setValues(new float[] { 1, 0, 0, 0, 1, 0, 0, 0, 1 }); x = 1x + 0y + 0z y = 0x + 1y + 0z z = 0x + 0y + 1z 通过canvas.drawBitmap(bmp, matrix, paint);创建bitmap 1.水平缩放0.5 2.垂直拉扯2倍 matrix.setScale(1.5f,1);//水平点放大到1.5f,垂直1 |
7 图形旋转 Matrix matrix = new Matrix(); matrix.setRotate(15); canvas.drawBitmap(bmp, matrix, paint); 消除锯齿 paint.setAntiAlias(true); 指定圆心的旋转 matrix.setRotate(15,bmp.getWidth()/2,bmp.getHeight()/2); Matrix matrix = new Matrix(); matrix.setRotate(15,bmp.getWidth()/2,bmp.getHeight()/2); alteredBitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, false); alteredImageView.setImageBitmap(alteredBitmap); |
8 图像平移: setTranslate(1.5f,-10); 9 镜子效果: matrix.setScale(-1, 1); matrix.postTranslate(bmp.getWidth(),0); 10 倒影效果: matrix.setScale(1, -1); matrix.postTranslate(0, bmp.getHeight()); |
11 图像颜色处理: 颜色矩阵 ColorMatrix cm = new ColorMatrix(); paint.setColorFilter(new ColorMatrixColorFilter(cm)); 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 New Red Value = 1*128 + 0*128 + 0*128 + 0*0 + 0 New Blue Value = 0*128 + 1*128 + 0*128 + 0*0 + 0 New Green Value = 0*128 + 0*128 + 1*128 + 0*0 + 0 New Alpha Value = 0*128 + 0*128 + 0*128 + 1*0 + 0 ColorMatrix cm = new ColorMatrix(); cm.set(new float[] { 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0 }); paint.setColorFilter(new ColorMatrixColorFilter(cm)); |
12 变换图像的亮度 ColorMatrix cm = new ColorMatrix(); float contrast = 2; cm.set(new float[] { contrast, 0, 0, 0, 0, 0, contrast, 0, 0, 0, 0, 0, contrast, 0, 0, 0, 0, 0, 1, 0 }); paint.setColorFilter(new ColorMatrixColorFilter(cm)); |
12 变换图像的亮度 ColorMatrix cm = new ColorMatrix(); float contrast = 2; cm.set(new float[] { contrast, 0, 0, 0, 0, 0, contrast, 0, 0, 0, 0, 0, contrast, 0, 0, 0, 0, 0, 1, 0 }); paint.setColorFilter(new ColorMatrixColorFilter(cm)); |
13 更改图片的饱和度: ColorMatrix cm = new ColorMatrix(); cm.setSaturation(.5f); paint.setColorFilter(new ColorMatrixColorFilter(cm)); |
14 图像合成: Bitmap drawingBitmap = Bitmap.createBitmap(bmp1.getWidth(),bmp1.getHeight(), bmp1.getConfig()); canvas = new Canvas(drawingBitmap); paint = new Paint(); canvas.drawBitmap(bmp1, 0, 0, paint); paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.MULTIPLY)); canvas.drawBitmap(bmp2, 0, 0, paint); |
15 按指定path上绘制文字 Paint paint = new Paint(); paint.setColor(Color.GREEN); paint.setTextSize(20); paint.setTypeface(Typeface.DEFAULT); Path p = new Path(); p.moveTo(20, 20); p.lineTo(100, 150); p.lineTo(200, 220); canvas.drawTextOnPath("Hello this is text on a path", p, 0, 0, paint); |
16 人脸识别 FaceDetector detector = new FaceDetector(faceBitmap.getWidth(), faceBitmap.getHeight(), 3); // 创建识别器 mNumFaces = detector.findFaces(faceBitmap, mFaces); // 识别 if (mNumFaces > 0) { for (int i = 0; i < mNumFaces; i++) { handleFace(mFaces[i]); //调用函数对人脸画面进行处理 } } |
关于人脸识别部分(网站地址是): http://www.faceplusplus.com/ |
============================================================================
1 场景:一张图片很大,放到手机上时需要对图片资源进行压缩以及缩放,编写如下界面的案例:
2 操作:当点击加载图片到内存时,图片从自己的手机sd卡中取到并显示。
3 ADT开发时,手机连接上电脑后,在Android开发工具中的”FileExplorer”中的文件位置如下:
4 下面开始编写代码,项目结构如下:
5 编写activity_main.xml,代码如下:
<LinearLayout 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" android:orientation="vertical" tools:context=".MainActivity" > <Button android:onClick="click" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="加载图片到内存" /> <ImageView android:id="@+id/iv" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> |
6 编写MainActivity,代码如下:
package com.itheima.loadimg; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapFactory.Options; import android.os.Bundle; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; public class MainActivity extends Activity { private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv); } public void click(View view) { // 相当消耗内存资源 根据图片的分辨率而定 // Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/photo.jpg"); // iv.setImageBitmap(bitmap); // 1.得到屏幕的宽高信息 WindowManager wm = getWindowManager(); int screenWidth = wm.getDefaultDisplay(). int screenHeight = wm.getDefaultDisplay(). System.out.println("屏幕宽高:" + screenWidth + "-" + screenHeight); // 2.得到图片的宽高。 BitmapFactory.Options opts = new Options();// 解析位图的附加条件 opts.inJustDecodeBounds = true;// 不去解析真实的位图,只是获取这个位图的头文件信息 Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard2/photo.jpg", opts); int bitmapWidth = opts.outWidth; int bitmapHeight = opts.outHeight; System.out.println("图片宽高: " + bitmapWidth + "-" + bitmapHeight); // 3.计算缩放比例 int dx = bitmapWidth / screenWidth; int dy = bitmapHeight / screenHeight; int scale = 1; if (dx > dy && dy > 1) { System.out.println("按照水平方法缩放,缩放比例:" + dx); scale = dx; } if (dy > dx && dx > 1) { System.out.println("按照垂直方法缩放,缩放比例:" + dy); scale = dy; } // 4.缩放加载图片到内存。 opts.inSampleSize = scale; opts.inJustDecodeBounds = false;// 真正的去解析这个位图。 bitmap = BitmapFactory.decodeFile("/mnt/sdcard2/photo.jpg", opts); iv.setImageBitmap(bitmap); } } |
7 编写AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.loadimg" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.loadimg.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> |
=============================================================================
1 图像的拷贝,翻转倒置。
要做如下效果(开始的效果图):
点击”拷贝一个位图”之后的效果:
2 编写代码,代码结构如下:
3 编写布局文件activity_main.xml
<LinearLayout 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" android:orientation="vertical" tools:context=".MainActivity" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="click" android:text="拷贝一个位图" /> <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> |
4 编写MainActivity,内容如下:
package com.itheima.copybitmap; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.os.Bundle; import android.view.View; import android.widget.ImageView; public class MainActivity extends Activity { private ImageView iv1,iv2; private Bitmap alterBitmap; private Bitmap srcBmp; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv1 = (ImageView) findViewById(R.id.iv1); iv2 = (ImageView) findViewById(R.id.iv2); //给第一个imageview默认设置一个位图 srcBmp = BitmapFactory.decodeResource(getResources(), R.drawable.tomcat); iv1.setImageBitmap(srcBmp); //创建原图的一个副本。 可修改 创建的是一个空白的图形。 alterBitmap = Bitmap.createBitmap(srcBmp.getWidth(), srcBmp.getHeight(),srcBmp.getConfig()); } /** * 创建原图 bm的一个拷贝。副本 * @param view */ public void click(View view) { //1.准备一个画板 在上面放上准备好的 空白的位图 Canvas canvas = new Canvas(alterBitmap); //2.准备一个画笔 Paint paint = new Paint(); paint.setColor(Color.BLACK); //3.画画 Matrix m = new Matrix(); m.setScale(1.0f, -1.0f); m.postTranslate(0, srcBmp.getHeight()); canvas.drawBitmap(srcBmp, m, paint); iv2.setImageBitmap(alterBitmap); //把原图的副本设置到界面中 } } |
拷贝放大图像的方式,只需要将上面的Click方法改成如下的方式:
/** * 创建原图bm的拷贝。副本 * @param view */ public void click(View view) { //1.准备一个画板 在上面放上准备好的 空白的位图 Canvas canvas = new Canvas(alterBitmap); //2.准备一个画笔 Paint paint = new Paint(); paint.setColor(Color.BLACK); //3.画画 Matrix m = new Matrix(); m.setScale(2.0f, 2.0f); canvas.drawBitmap(srcBmp, m, paint); //把原图的副本设置到界面上。 iv2.setImageBitmap(alterBitmap); } |
运行效果图如下:
如果旋转,只需要将Scale处的代码换成:
m.setRotate(180, srcBmp.getWidth()/2,srcBmp.getHeight()/2);
如果想变换颜色,需要将上面的代码换成:
/** * 创建原图 bm的一个拷贝。副本 * @param view */ public void click(View view){ //1.准备一个画板 在上面放上准备好的 空白的位图 Canvas canvas = new Canvas(alterBitmap); //2.准备一个画笔 Paint paint = new Paint(); paint.setColor(Color.BLACK); //3.画画 Matrix m = new Matrix(); ColorMatrix cm = new ColorMatrix(); cm.set(new float[] { 0.5f, 0, 0, 0, 0, 0, 0.8f, 0, 0, 0, 0, 0, 0.6f, 0, 0, 0, 0, 0, 1, 0 }); paint.setColorFilter(new ColorMatrixColorFilter(cm)); canvas.drawBitmap(srcBmp, m, paint); iv2.setImageBitmap(alterBitmap);//把原图的副本设置到界面上。 } |
业务场景:
(1)、手指在一张美女图片上移动时,移动部分的图片会变成成透明,然后显示底部的另外一张图片
(2)、当手指离开的时候播放音乐…
应用效果图:
1 编写应用,代码结构如下:
2、编写布局文件activity_main.xml
<RelativeLayout 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" tools:context=".MainActivity" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:src="@drawable/after" /> <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true"/> </RelativeLayout> |
3、编写MainActivity
package com.itheima.play; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.media.MediaPlayer; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.ImageView; public class MainActivity extends Activity { private ImageView iv; // 可以修改的位图 private Bitmap alertBitmap; private Canvas canvas; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv); Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pre); // 创建一个空白的原图的拷贝 alertBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig()); canvas = new Canvas(alertBitmap); Paint paint = new Paint(); paint.setColor(Color.BLACK); canvas.drawBitmap(bitmap, new Matrix(), paint); iv.setImageBitmap(alertBitmap); iv.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN:// 手指按下屏幕 System.out.println("action down"); break; case MotionEvent.ACTION_MOVE:// 手指在屏幕上移动 int x = (int) event.getX(); int y = (int) event.getY(); System.out.println("设置("+x+","+y+")透明颜色"); for(int i=-4;i<5;i++){ for(int j=-4;j<5;j++){ try{ alertBitmap.setPixel(x+i, y+j, Color.TRANSPARENT); } catch (Exception e) { e.printStackTrace(); } } } iv.setImageBitmap(alertBitmap); break; case MotionEvent.ACTION_UP:// 手指离开屏幕 MediaPlayer.create(getApplicationContext(), R.raw.higirl).start(); break; } return true;//可以重复循环的处理事件 } }); } } |
4 Android的清单文件如下:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.play" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.play.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> |
19_Android中图片处理原理篇,关于人脸识别网站,图片加载到内存,图片缩放,图片翻转倒置,网上撕衣服游戏案例编写相关推荐
- 19_Android中图片处理原理篇,关于人脸识别网站,图片加载到内存,图片缩放,图片翻转倒置,网上撕衣服游戏案例编写...
1 加载图片到内存 (1).数码相机照片特别是大于3m以上的,内存吃不消,会报OutOfMemoryError,若是想只显示原图片的1/8,可以通过BitmapFactory.Options来实现,具 ...
- 19_Android中图片处理原理篇,关于人脸识别站点,图片载入到内存,图片缩放,图片翻转倒置,网上撕衣服游戏案例编写...
1 载入图片到内存 (1).数码相机照片特别是大于3m以上的,内存吃不消,会报OutOfMemoryError,若是想仅仅显示原图片的1/8,能够通过BitmapFactory.Options来实现. ...
- 19 Android中图片处理原理篇,关于人脸识别网站,图片加载到内存,图片缩放,图片翻转倒置,网上撕衣服游戏案例编写
首先给大家分享一个巨牛巨牛的人工智能教程,是我无意中发现的.教程不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵段子,像看小说一样,哈哈-我正在学习中,觉得太牛了,所以分享给大家!点这里可以跳转 ...
- 人脸识别的模板加载问题
人脸识别的模板加载问题 最近在做一个Android的考勤机项目,要求支持人脸.指纹.刷卡签到,人脸部分用的是中控的人脸识别模块. 在测试环境下人脸识别一切正常,切换到现场环境后刚开始也都没问题,过了几 ...
- android加载大量图片内存优化,Android图片加载内存优化
利用BitmapFactory.Options实现图片内存优化 通过设置options.inPreferredConfig控制内存占用 首先准备了一张1280x800的blue_bg.png图片,我们 ...
- python 下载图片到内存卡_python - 获取图像大小而不将图像加载到内存中
如果您不关心图像内容,PIL可能是一种过度杀伤力. 我建议解析python magic模块的输出: >>> t = magic.from_file('teste.png') > ...
- 深度解析——图片加载到内存中的大小计算内存优化
本篇文章已授权微信公众号 hongyangAndroid (鸿洋)独家发布 最近封装了个高斯模糊组件,正好将图片相关的理论基础也梳理了下,所以,这次就来讲讲,在 Android 中,怎么计算一张图片在 ...
- Glide加载自签名的https图片
前言 Glide默认加载http或者通过CA认证了的https图片都是没问题的,但是当加载自签名的https图片的时候就会报如下错误(证书路径验证异常). 一.原理 对于加载自签名的https图片,我 ...
- android drawable 图片大小,不同的drawable文件夹下图片加载到内存后图片尺寸大小的分析...
先说结论: 不同drawable文件下图片在同一手机图片尺寸是不同的 同一个drawable文件夹下的图片在不同分辨率的手机图片尺寸是不同的 先聊下DP 要在密度不同的屏幕上保留界面的可见尺寸,您必须 ...
最新文章
- 解决vscode下载速度慢的方法
- BZOJ 1854: [Scoi2010]游戏( 二分图最大匹配 )
- 怎么在同一页中分页_分库分表业界难题,跨库分页的几种常见方案
- U盘版便携式Linux制作, casper-rw 解析
- js删除数组中指定元素_js中数组操作详解
- POJ NOI MATH-7832 最接近的分数
- MySql 数据类型 - 整型
- 新旧_飘云羽逸_新浪博客
- AHP权重计算方法案例
- 华为手机图标怎么变小_华为手机怎么设置图标由大变小
- 改变Ubuntu18.04初始键盘布局
- 已经不能再简单的UE4中播放视频没有声音的解决方案
- A. Captain Flint and Crew Recruitment
- 深信服AC1000路由部署模式怎么配置线路负载均衡
- 什么是CI/CD,以及我所熟知的CI/CD工具都是有哪些?
- ajax发送put请求参数,请求参数和PUT方法(Request params and PUT method)
- 用Cyberduck将4EVERLAND Bucket挂载到本地,构建属于自己的Web3云网盘
- 欧洲为何没有互联网巨头?
- 为什么英语是程序员的竞争力?
- 关机时候计算机更新,电脑关机时提示更新,能否强制关机?
热门文章
- Python可视化中Matplotlib(3.线条的详细样式及线性、保存图片、plot的详细风格和样式)、背景色、点和线的详细设置
- 高斯赛尔德、牛顿拉尔逊matlab潮流计算
- opencv进阶学习笔记10:图像金字塔和图像梯度
- Seaborn(2)调色板
- VTK:提取选择 OriginalId用法实战
- boost::spirit模块演示 AST 生成的计算器示例,AST一旦创建就会被遍历
- boost::mpl模块实现copy_if相关的测试程序
- boost::math模块演示负二项分布使用的简单示例的测试程序
- Boost:基于boost::asio的延迟udp服务器测试程序
- ITK:计算边缘电势