Android(安卓)以图找图功能
16lz
2021-01-24
到2016年的最后一个月了,总得写点什么或者记录点什么。恩,就记录一下,我当时做以图找图,这个功能的过程和结果吧。以图找图简而言之就是确认小图是否属于大图的一部分。
这个方法不是百分百能找到的,也可能找到错误的图片,如果2个大图和小图的相似度很高的话。
1.序
刚开始做这个功能的时候,我一直在往误区上找,认为这是Android的项目,然后一直在找android方面的东西,也确实找到了,但这方面根本没有相关的DEMO(其实也是因为个人有点懒,有现成的,总是想直接用。)
然后想到了其实可以从java方面图片,这样就发现很多都是通过像素点进行查找的,但原理上是没错的就是查找的过程就有点慢了。在电脑上运行当然很快,但放在android上就很慢了,毕竟你需要对比每个像素点。
最后是通过计算哈希值的方法,来进行图片的查找。虽然也需要一块一块的查(就是根据原图片的大小,然后在目标图片上查找),然后得出结论是否是属于目标图片的。
2.代码
/** 小图是否属于大图 * @param mubiao 目标图片(小图)地址 * @param yuantu 源图片(大图)地址 * @return * @throws IOException */private static boolean FindImg(String mubiao, String yuantu) throws IOException{boolean isFind = false; Bitmap yuantusource = BitmapFactory.decodeFile(yuantu, null); Bitmap mubiaosource = BitmapFactory.decodeFile(mubiao, null); // huidu("yuantu" , yuantu);// huidu("mubiao" , mubiao); String mubiaoHashCode; String yuantuHashCode; Bitmap jiequsource; int width = yuantusource.getWidth(); int height = yuantusource.getHeight(); int Mwidth = mubiaosource.getWidth(); int Mheight = mubiaosource.getHeight(); mubiaoHashCode = BufproduceFingerPrint(mubiaosource); //通过循环来查找图片(就是从左上到右下) for(int i=0;i= avgPixel) { comps[i] = 1; } else { comps[i] = 0; } } // 第五步,计算哈希值。 // 将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。 StringBuffer hashCode = new StringBuffer(); for (int i = 0; i < comps.length; i += 4) { int result = comps[i] * (int) Math.pow(2, 3) + comps[i + 1] * (int) Math.pow(2, 2) + comps[i + 2] * (int) Math.pow(2, 1) + comps[i + 2]; hashCode.append(binaryToHex(result)); } // 得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。 return hashCode.toString(); } private static char binaryToHex(int binary) { char ch = ' '; switch (binary) { case 0: ch = '0'; break; case 1: ch = '1'; break; case 2: ch = '2'; break; case 3: ch = '3'; break; case 4: ch = '4'; break; case 5: ch = '5'; break; case 6: ch = '6'; break; case 7: ch = '7'; break; case 8: ch = '8'; break; case 9: ch = '9'; break; case 10: ch = 'a'; break; case 11: ch = 'b'; break; case 12: ch = 'c'; break; case 13: ch = 'd'; break; case 14: ch = 'e'; break; case 15: ch = 'f'; break; default: ch = ' '; } return ch; } /** * 2个是否相同,0为相同 * @param sourceHashCode * @param hashCode * @return */ public static int hammingDistance(String sourceHashCode, String hashCode) { int difference = 0; int len = sourceHashCode.length(); for (int i = 0; i < len; i++) { if (sourceHashCode.charAt(i) != hashCode.charAt(i)) { difference++; } } return difference; }
import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.BitmapFactory;import android.graphics.Matrix;public class ImageHelper {public static Bitmap zoomImage(Bitmap bgimage, double newWidth, double newHeight) { // 获取这个图片的宽和高 float width = bgimage.getWidth(); float height = bgimage.getHeight(); // 创建操作图片用的matrix对象 Matrix matrix = new Matrix(); // 计算宽高缩放率 float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; // 缩放图片动作 matrix.postScale(scaleWidth, scaleHeight); Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width, (int) height, matrix, true); return bitmap; } private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 int options = 100; while ( baos.toByteArray().length / 1024>100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩 baos.reset();//重置baos即清空baos image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中 options -= 10;//每次都减少10 } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中 Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片 return bitmap; } public static int rgbToGray(int pixels) { // int _alpha = (pixels >> 24) & 0xFF; int _red = (pixels >> 16) & 0xFF; int _green = (pixels >> 8) & 0xFF; int _blue = (pixels) & 0xFF; return (int) (0.3 * _red + 0.59 * _green + 0.11 * _blue); }//// public static int average(int[] pixels) { float m = 0; for (int i = 0; i < pixels.length; ++i) { m += pixels[i]; } m = m / pixels.length; return (int) m; }}
3.结束
恩,这就是以图找图的所有代码=-=恩,是通过网上方法总结出来了的=-=就这样了。
更多相关文章
- android高仿微信视频编辑页-视频多张图片提取
- 我的工具太少了之Android无限轮播图片,最后一张过度动画很重要
- Android(安卓)zip文件中读取图片实现Gallery放大缩小,移动,图片弹
- Android(安卓).9.png图片的制作与使用
- Android(安卓)PowerImageView实现,可以播放动画的强大ImageView
- Android(安卓)判断imageview角度并旋转
- Android中自定义drawable states
- android实现点击按钮控制图片切换
- 一起学android之给图片添加涂鸦(文字)(37)