1、佈局中顯示圖片
在佈局的xml中佈局圖片的時候用ImageView,用src去指定圖片所在位置。以下代碼所示,指定的就是工程目錄(/res/drawable)中文件名爲unknown.png的圖片。
這裏要注意的是Android Studio在佈局時只認png格式的圖片,即便是jpeg格式,僅把後綴改成png也不行,編譯時會不經過。android
<ImageView android:id="@+id/iv_mytest" android:src="@drawable/unknown" />
可是,也不等於jpeg格式的圖片就不能顯示,咱們能夠經過以下代碼處理的方式來展現到界面上。緩存
String imgPath = Environment.getExternalStorageDirectory() + "test.jpg"; ImageView iv_mytest = (ImageView) findViewById(R.id.iv_mytest); iv_mytest.setVisibility(View.VISIBLE); if(!imgPath.equals("")) { Bitmap tempBitmap = BitmapFactory.decodeFile(imgPath); iv_mytest.setImageBitmap(tempBitmap);//顯示圖片 }
2、拍照後顯示圖片
拍照流程爲獲取緩存圖片路徑->進入拍照界面->拍照界面拍照後自動存到緩存圖片路徑中->進入回調函數->對緩存圖片進行處理(如旋轉縮放等)並存儲到本身指定位置->刪除緩存路徑圖片。
具體代碼以下所示:ide
private String tmpfilename = ""; //調用拍照界面 private void photograph(){ try { // 跳轉至拍照界面 String sdStatus = Environment.getExternalStorageState(); if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 檢測sd是否可用 ToastUtil.showToastMsgError(MyTestActivity.this,"SD card is not avaiable/writeable right now."); return; } tmpfilename=getTempFilePath(); File out = new File(tmpfilename); Intent intentPhote = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (Build.VERSION.SDK_INT >= 24) { //臨時添加一個拍照權限 intentPhote.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //經過FileProvider獲取uri contentUri = FileProvider.getUriForFile(getActivity(), "com.tmri.rfid.eri.internet.fileProvider", out); intentPhote.putExtra(MediaStore.EXTRA_OUTPUT, contentUri); } else { mImageCaptureUri = Uri.fromFile(out); intentPhote.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri); } startActivityForResult(intentPhote, 1); }catch (Exception e) { } } /** * 獲取原緩存圖片存儲路徑 * @return */ private String getTempFilePath() { // 照片全路徑 String fileName = ""; // 文件夾路徑 String pathUrl = Environment.getExternalStorageDirectory()+"/tmp/"; imagename = "mytest.png"; File file = new File(pathUrl); file.mkdirs();// 建立文件夾 fileName = pathUrl + imagename; return fileName; } //拍取照後的回調 @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1 && resultCode == Activity.RESULT_OK) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; // 設置了此屬性必定要記得將值設置爲false Bitmap bitmap = BitmapFactory.decodeFile(tmpfilename); // 防止OOM發生 options.inJustDecodeBounds = false; saveMyBitmap(imagename,bitmap); File old = new File(Environment.getExternalStorageDirectory() + "/tmp/"); FileUtil.deleteFile(old);//刪除緩存圖片 String resultMsg = "圖片已保存"; ToastUtil.showToastMsgSuccess(this, resultMsg); } } //將圖像保存到SD卡中 public void saveMyBitmap(String bitName, Bitmap mBitmap) { String thisDate = formatter_date.format(new Date()); File f = FileUtil.getFilePath(Environment.getExternalStorageDirectory() + "/rfid/prehairpin/"+thisDate+"/", bitName); String realfilepath = f.getPath(); FileOutputStream fOut = null; try { fOut = new FileOutputStream(f); } catch (Exception e) { e.printStackTrace(); } Matrix matrix = new Matrix(); // 按照固定大小對圖片進行縮放 matrix.postScale(0.3f, 0.3f); System.out.println(mBitmap.getWidth() + mBitmap.getHeight()); if (mBitmap.getHeight() < mBitmap.getWidth()) { matrix.postRotate(90); //翻轉90度 } mBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true); mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut); try { fOut.write(("my secret message").getBytes());//我在這邊偷偷給圖片結尾藏了一些信息 fOut.flush(); } catch (IOException e) { e.printStackTrace(); } try { fOut.close(); } catch (IOException e) { e.printStackTrace(); } }
3、圖片的處理
旋轉、縮放等操做咱們是經過Matrix來處理的,Matrix還有不少其餘圖形處理的方法,能夠另開一篇去講述。函數
Matrix matrix = new Matrix(); // 按照固定大小對圖片進行縮放 matrix.postScale(0.3f, 0.3f); if (mBitmap.getHeight() < mBitmap.getWidth()) { matrix.postRotate(90); //翻轉90度 } mBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true); mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
上面是按比例縮小,下面是按固定分辨率縮放佈局
Matrix matrix = new Matrix(); int dstWidth = 800; int dstHeight = 600; if (mBitmap.getHeight() > mBitmap.getWidth()) { matrix.postRotate(90); //翻轉90度 final float sx = dstWidth / (float) mBitmap.getHeight(); final float sy = dstHeight / (float) mBitmap.getWidth(); matrix.postScale(sx, sy); }else{ final float sx = dstWidth / (float) mBitmap.getWidth(); final float sy = dstHeight / (float) mBitmap.getHeight(); matrix.postScale(sx, sy); } Bitmap endBit = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true); endBit.compress(Bitmap.CompressFormat.JPEG, 100, fOut);//jpeg格式縮放的圖片大小基本只佔png的一半
保存圖片,並將字符存入圖片(有時候拍照後但願將一些信息與圖片綁定起來,直接記錄文件名又擔憂被人篡改,就想到了這種在圖片文件末尾記錄一些信息的方式)post
String thisDate = formatter_date.format(new Date()); File f = FileUtil.getFilePath(Environment.getExternalStorageDirectory() + "/rfid/prehairpin/"+thisDate+"/", bitName); String realfilepath = f.getPath(); FileOutputStream fOut = null; try { fOut = new FileOutputStream(f); } catch (Exception e) { e.printStackTrace(); } //我在這邊偷偷給圖片結尾藏了一些信息 try { fOut.write(("my secret message").getBytes()); fOut.flush(); } catch (IOException e) { e.printStackTrace(); } try { fOut.close(); } catch (IOException e) { e.printStackTrace(); }
4、圖片格式的差別png、jpeg由於格式的差別,在內部添加字符信息時會不同,好比png格式結尾處就是圖片信息,因此添加的話直接在末尾添加就能夠;而jpeg不行,jpeg末尾是有固定格式信息的,直接加載末尾雖然不影響圖片顯示,可是在解析時就會由於位置偏移解析出來的字符信息就不對了。這一塊內容還有待去深刻研究下,當時也只是試驗了兩種格式,發現了這一問題。
更新於20190711,經嘗試jpeg也能夠再末尾寫入信息,且jpeg縮放的圖片大小僅佔png格式縮放的圖片一半大小。
可是,此時jpeg格式的圖片直接解析是沒有問題的,一經上傳就沒法解析末尾寫入的信息了。
爲什麼通過上傳後末尾的信息沒法解析的問題,還有待研究!還望知道的朋友不吝賜教!ui