package com.andbase.demo.activity; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import android.content.ActivityNotFoundException; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Paint.Align; import android.graphics.Typeface; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.Button; import android.widget.GridView; import android.widget.ImageView; import android.widget.LinearLayout; import com.ab.activity.AbActivity; import com.ab.model.AbResult; import com.ab.task.AbTaskItem; import com.ab.task.AbTaskListener; import com.ab.task.thread.AbTaskPool; import com.ab.util.AbDialogUtil; import com.ab.util.AbFileUtil; import com.ab.util.AbImageUtil; import com.ab.util.AbLogUtil; import com.ab.util.AbMathUtil; import com.ab.util.AbStrUtil; import com.ab.util.AbToastUtil; import com.ab.util.AbViewUtil; import com.ab.view.chart.CategorySeries; import com.ab.view.chart.ChartFactory; import com.ab.view.chart.PointStyle; import com.ab.view.chart.XYMultipleSeriesDataset; import com.ab.view.chart.XYMultipleSeriesRenderer; import com.ab.view.chart.XYSeriesRenderer; import com.ab.view.titlebar.AbTitleBar; import com.andbase.R; import com.andbase.demo.adapter.ImageShowAdapter; import com.andbase.global.MyApplication; public class PHashActivity extends AbActivity { private MyApplication application; private GridView mGridView = null; private ImageShowAdapter mImagePathAdapter = null; private ArrayList<String> mPhotoList = new ArrayList<String>(); private View mAvatarView = null; /* 用来标识请求照相功能的activity */ private static final int CAMERA_WITH_DATA = 3023; /* 用来标识请求gallery的activity */ private static final int PHOTO_PICKED_WITH_DATA = 3021; /* 用来标识请求裁剪图片后的activity */ private static final int CAMERA_CROP_DATA = 3022; /* 拍照的照片存储位置 */ private File PHOTO_DIR = null; // 照相机拍照得到的图片 private File mCurrentPhotoFile; private String mFileName; private ImageView myImage = null; private AbResult mAbResult = null; private StringBuffer filePathAll = null; private List<String> hashCodes = new ArrayList<String>(); private List<File> files = new ArrayList<File>(); private HashMap<Integer, Integer> hashCodesAndDis = new HashMap<Integer, Integer>(); private AbTaskPool mAbTaskPool = AbTaskPool.getInstance(); private List<int[]> colorHistogram = new ArrayList<int[]>(); private LinearLayout mChartLinearLayout = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setAbContentView(R.layout.p_hash); application = (MyApplication) abApplication; AbTitleBar mAbTitleBar = this.getTitleBar(); mAbTitleBar.setTitleText(R.string.phash_name); mAbTitleBar.setLogo(R.drawable.button_selector_back); mAbTitleBar.setTitleBarBackground(R.drawable.top_bg); mAbTitleBar.setTitleTextMargin(10, 0, 0, 0); mAbTitleBar.setLogoLine(R.drawable.line); initTitleRightLayout(); mGridView = (GridView)findViewById(R.id.myGrid); mImagePathAdapter = new ImageShowAdapter(this, mPhotoList,116,116); mGridView.setAdapter(mImagePathAdapter); mAvatarView = mInflater.inflate(R.layout.choose_avatar, null); //要显示图形的View mChartLinearLayout = (LinearLayout) findViewById(R.id.chart01); //初始化图片保存路径 String photo_dir = AbFileUtil.getImageDownloadDir(this); if(AbStrUtil.isEmpty(photo_dir)){ AbToastUtil.showToast(PHashActivity.this,"存储卡不存在"); }else{ PHOTO_DIR = new File(photo_dir); } Button albumButton = (Button)mAvatarView.findViewById(R.id.choose_album); Button camButton = (Button)mAvatarView.findViewById(R.id.choose_cam); Button cancelButton = (Button)mAvatarView.findViewById(R.id.choose_cancel); albumButton.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { AbDialogUtil.removeDialog(PHashActivity.this); // 从相册中去获取 try { Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null); intent.setType("image/*"); startActivityForResult(intent, PHOTO_PICKED_WITH_DATA); } catch (ActivityNotFoundException e) { AbToastUtil.showToast(PHashActivity.this,"没有找到照片"); } } }); camButton.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { AbDialogUtil.removeDialog(PHashActivity.this); doPickPhotoAction(); } }); cancelButton.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { AbDialogUtil.removeDialog(PHashActivity.this); } }); Button addBtn = (Button)findViewById(R.id.addBtn); Button createBtn = (Button)findViewById(R.id.createBtn); myImage = (ImageView)findViewById(R.id.myImage); addBtn.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { if(filePathAll==null){ AbToastUtil.showToast(PHashActivity.this,"请先创建图片索引!"); }else{ AbDialogUtil.showDialog(mAvatarView); } } }); createBtn.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { AbDialogUtil.showProgressDialog(PHashActivity.this,R.drawable.progress_circular,"正在查询..."); final AbTaskItem item = new AbTaskItem(); item.setListener(new AbTaskListener() { @Override public void update() { AbDialogUtil.removeDialog(PHashActivity.this); AbToastUtil.showToast(PHashActivity.this,"创建图片索引完成!"); } @Override public void get() { try { filePathAll = new StringBuffer(); hashCodes.clear(); hashCodesAndDis.clear(); files.clear(); colorHistogram.clear(); AbLogUtil.prepareLog(PHashActivity.this); //查询手机中所有图片 if(!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){ //无sd卡 }else{ //有sd卡 File pathSD = Environment.getExternalStorageDirectory(); File fileDirectory = new File(pathSD.getAbsolutePath() + File.separator + "DCIM" + File.separator); listFile(fileDirectory); } //循环所有图片检查相似度 String fileStrs = filePathAll.toString(); if(!AbStrUtil.isEmpty(fileStrs)){ if(fileStrs.indexOf(",")!=-1){ String [] paths = fileStrs.split(","); for(int i=0;i<paths.length;i++){ String str = paths[i]; if(!AbStrUtil.isEmpty(str)){ files.add(new File(str)); } } } } //计算图片的hash for(int i=0;i<files.size();i++){ File f = files.get(i); AbLogUtil.d(PHashActivity.this, "图片的路径是 = " + f.getPath()); Bitmap bitmap = AbFileUtil.getBitmapFromSD(f); if(bitmap==null){ //图片有问题 files.remove(i); i--; break; }else{ //计算hash String hashCode = AbImageUtil.getDCTHashCode(bitmap); hashCodes.add(hashCode); AbLogUtil.d(PHashActivity.this,"hashCodes add:"+i+":"+hashCode); //颜色分布 Bitmap bitmapT = AbImageUtil.getCutBitmap(bitmap,360,360); int [] colors = AbImageUtil.getColorHistogram(bitmapT); colorHistogram.add(colors); AbImageUtil.releaseBitmap(bitmap); } } AbLogUtil.d(PHashActivity.this, "创建索引",true); } catch (Exception e) { AbToastUtil.showToastInThread(PHashActivity.this,e.getMessage()); } }; }); mAbTaskPool.execute(item); } }); } private void initTitleRightLayout() { } /** * 描述:从照相机获取 */ private void doPickPhotoAction() { String status = Environment.getExternalStorageState(); //判断是否有SD卡,如果有sd卡存入sd卡在说,没有sd卡直接转换为图片 if (status.equals(Environment.MEDIA_MOUNTED)) { doTakePhoto(); } else { AbToastUtil.showToast(PHashActivity.this,"没有可用的存储卡"); } } /** * 拍照获取图片 */ protected void doTakePhoto() { try { mFileName = System.currentTimeMillis() + ".jpg"; mCurrentPhotoFile = new File(PHOTO_DIR, mFileName); Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, null); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mCurrentPhotoFile)); startActivityForResult(intent, CAMERA_WITH_DATA); } catch (Exception e) { AbToastUtil.showToast(PHashActivity.this,"未找到系统相机程序"); } } /** * 描述:因为调用了Camera和Gally所以要判断他们各自的返回情况, * 他们启动时是这样的startActivityForResult */ protected void onActivityResult(int requestCode, int resultCode, Intent mIntent) { if (resultCode != RESULT_OK){ return; } switch (requestCode) { case PHOTO_PICKED_WITH_DATA: Uri uri = mIntent.getData(); String currentFilePath = getPath(uri); if(!AbStrUtil.isEmpty(currentFilePath)){ Intent intent1 = new Intent(this, CropImageActivity.class); intent1.putExtra("PATH", currentFilePath); startActivityForResult(intent1, CAMERA_CROP_DATA); }else{ AbToastUtil.showToast(PHashActivity.this,"未在存储卡中找到这个文件"); } break; case CAMERA_WITH_DATA: AbLogUtil.d(PHashActivity.this, "将要进行裁剪的图片的路径是 = " + mCurrentPhotoFile.getPath()); String currentFilePath2 = mCurrentPhotoFile.getPath(); Intent intent2 = new Intent(this, CropImageActivity.class); intent2.putExtra("PATH",currentFilePath2); startActivityForResult(intent2,CAMERA_CROP_DATA); break; case CAMERA_CROP_DATA: mChartLinearLayout.removeAllViews(); String path = mIntent.getStringExtra("PATH"); AbLogUtil.d(PHashActivity.this, "裁剪后得到的图片的路径是 = " + path); Bitmap bitmap = AbFileUtil.getBitmapFromSD(new File(path)); myImage.setImageBitmap(bitmap); hashCodesAndDis.clear(); mPhotoList.clear(); mImagePathAdapter.notifyDataSetChanged(); AbViewUtil.setAbsListViewHeight(mGridView,3,25); //先过滤颜色相似 //颜色分布 int [] sourceColors = AbImageUtil.getColorHistogram(bitmap); //获取这个图的hashcode String sourceHashCode = AbImageUtil.getDCTHashCode(bitmap); AbLogUtil.d(PHashActivity.this,"this image sourceHashCode:"+sourceHashCode); //计算距离 for(int i = 0;i<hashCodes.size();i++){ String hashCode = hashCodes.get(i); int distanceNew = AbImageUtil.hammingDistance(sourceHashCode, hashCode); if(distanceNew<5){ hashCodesAndDis.put(i,distanceNew); } } //排序按距离升序 Set set = hashCodesAndDis.entrySet(); Map.Entry[] hashCodesAndDisNew = (Map.Entry[]) set.toArray(new Map.Entry[set.size()]); Arrays.sort(hashCodesAndDisNew, new Comparator() { public int compare(Object arg0, Object arg1) { Long key1 = Long.valueOf(((Map.Entry) arg0).getValue().toString()); Long key2 = Long.valueOf(((Map.Entry) arg1).getValue().toString()); return key1.compareTo(key2); } }); //显示 for(int i=0;i<hashCodesAndDisNew.length;i++){ String pathNew = files.get((Integer)hashCodesAndDisNew[i].getKey()).getPath(); AbLogUtil.d(PHashActivity.this,"匹配结果:"+pathNew+":"+hashCodesAndDisNew[i].getValue()); mImagePathAdapter.addItem(mImagePathAdapter.getCount(),pathNew); int [] sourceColors1 = colorHistogram.get(i); for(int j = 0;j<sourceColors1.length;j++){ sourceColors1[j] = sourceColors[j]-sourceColors1[j]; } createChart(sourceColors1,"图片"+i); AbViewUtil.setAbsListViewHeight(mGridView,3,25); } break; } } /** * 从相册得到的url转换为SD卡中图片路径 */ public String getPath(Uri uri) { if(AbStrUtil.isEmpty(uri.getAuthority())){ return null; } String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = managedQuery(uri, projection, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); String path = cursor.getString(column_index); return path; } public void listFile(File directory){ if(directory.isDirectory()){ File[] files = directory.listFiles(); if(files!=null){ for(int i=0;i<files.length;i++){ if(files[i].isDirectory()){ listFile(files[i]); }else{ String fName = files[i].getName(); String end = fName.substring(fName.lastIndexOf(".")+1,fName.length()).toLowerCase(); if(end.equals("jpg")||end.equals("png")){ filePathAll.append(files[i].getPath()+","); } } } } } } public void createChart(int [] colorsArea,String title){ LinearLayout chartView = (LinearLayout)mInflater.inflate(R.layout.chart_view_item, null); //说明文字 String[] titles = new String[] { "颜色差"}; //数据 List<double[]> values = new ArrayList<double[]>(); //每个数据点的颜色 List<int[]> colors = new ArrayList<int[]>(); //每个数据点的简要 说明 List<String[]> explains = new ArrayList<String[]>(); values.add(AbMathUtil.intToDoubleArray(colorsArea)); int [] colorsPoint = new int[colorsArea.length]; //红绿蓝4个区 for(int i=0;i<colorsArea.length;i++){ if(i/16>3){ colorsPoint[i] = Color.rgb(255, 63, 63); }else if(i/16>2){ colorsPoint[i] = Color.rgb(191, 127, 127); }else if(i/16>1){ colorsPoint[i] = Color.rgb(127, 191, 191); }else{ colorsPoint[i] = Color.rgb(63, 255, 255); } } colors.add(colorsPoint); explains.add(new String[colorsArea.length]); //柱体或者线条颜色 int[] mSeriescolors = new int[] { Color.rgb(153, 204, 0)}; //创建渲染器 XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer(); int length = mSeriescolors.length; for (int i = 0; i < length; i++) { //创建SimpleSeriesRenderer单一渲染器 XYSeriesRenderer r = new XYSeriesRenderer(); //SimpleSeriesRenderer r = new SimpleSeriesRenderer(); //设置渲染器颜色 r.setColor(mSeriescolors[i]); r.setFillBelowLine(true); r.setFillBelowLineColor(mSeriescolors[i]); r.setFillPoints(true); r.setPointStyle(PointStyle.CIRCLE); r.setLineWidth(1); r.setChartValuesTextSize(16); //加入到集合中 renderer.addSeriesRenderer(r); } //坐标轴标题文字大小 renderer.setAxisTitleTextSize(16); //图形标题文字大小 renderer.setChartTitleTextSize(25); //轴线上标签文字大小 renderer.setLabelsTextSize(15); //说明文字大小 renderer.setLegendTextSize(15); //图表标题 renderer.setChartTitle(title); //X轴标题 renderer.setXTitle("区间"); //Y轴标题 renderer.setYTitle("数量"); //X轴最小坐标点 renderer.setXAxisMin(-2); //X轴最大坐标点 renderer.setXAxisMax(64); //Y轴最小坐标点 renderer.setYAxisMin(-20000); //Y轴最大坐标点 renderer.setYAxisMax(20000); //坐标轴颜色 renderer.setAxesColor(Color.rgb(51, 181, 229)); renderer.setXLabelsColor(Color.rgb(51, 181, 229)); renderer.setYLabelsColor(0,Color.rgb(51, 181, 229)); //设置图表上标题与X轴与Y轴的说明文字颜色 renderer.setLabelsColor(Color.GRAY); //renderer.setGridColor(Color.GRAY); //设置字体加粗 renderer.setTextTypeface("sans_serif", Typeface.BOLD); //设置在图表上是否显示值标签 renderer.getSeriesRendererAt(0).setDisplayChartValues(false); //显示屏幕可见取区的XY分割数 renderer.setXLabels(10); renderer.setYLabels(10); //X刻度标签相对X轴位置 renderer.setXLabelsAlign(Align.CENTER); //Y刻度标签相对Y轴位置 renderer.setYLabelsAlign(Align.LEFT); renderer.setPanEnabled(false, false); renderer.setZoomEnabled(false); renderer.setZoomRate(1.1f); renderer.setBarSpacing(0.5f); //标尺开启 renderer.setScaleLineEnabled(false); //设置标尺提示框高 renderer.setScaleRectHeight(10); //设置标尺提示框宽 renderer.setScaleRectWidth(150); //设置标尺提示框背景色 renderer.setScaleRectColor(Color.argb(150, 52, 182, 232)); renderer.setScaleLineColor(Color.argb(175, 150, 150, 150)); renderer.setScaleCircleRadius(35); //第一行文字的大小 renderer.setExplainTextSize1(20); //第二行文字的大小 renderer.setExplainTextSize2(20); //临界线 //double[] limit = new double[]{15000,12000,4000,9000}; //renderer.setmYLimitsLine(limit); //int[] colorsLimit = new int[] { Color.rgb(100, 255,255),Color.rgb(100, 255,255),Color.rgb(0, 255, 255),Color.rgb(0, 255, 255) }; //renderer.setmYLimitsLineColor(colorsLimit); //显示表格线 renderer.setShowGrid(true); //如果值是0是否要显示 renderer.setDisplayValue0(true); //创建渲染器数据填充器 XYMultipleSeriesDataset mXYMultipleSeriesDataset = new XYMultipleSeriesDataset(); for (int i = 0; i < length; i++) { CategorySeries series = new CategorySeries(titles[i]); double[] v = values.get(i); int[] c = colors.get(i); String[] e = explains.get(i); int seriesLength = v.length; for (int k = 0; k < seriesLength; k++) { //设置每个点的颜色 series.add(v[k],c[k],e[k]); } mXYMultipleSeriesDataset.addSeries(series.toXYSeries()); } //背景 renderer.setApplyBackgroundColor(true); renderer.setBackgroundColor(Color.rgb(235, 235, 235)); renderer.setMarginsColor(Color.rgb(235, 235, 235)); //线图 View chart = ChartFactory.getAreaChartView(this,mXYMultipleSeriesDataset,renderer,0.2f); chartView.addView(chart); chartView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 250)); mChartLinearLayout.addView(chartView); } }