十年专注于网站建设与互联网应用开发,低调、有情怀的网络应用服务商!
南昌百恒科技微信公众号 扫一扫关注
tel-icon全国服务热线:400-680-9298,0791-88117053
扫一扫关注百恒科技微信公众号

安卓开发之缩放和显示位图

百恒网络 2018-12-04 15:37:10 75
       使用相机intent,我们就可以成功拍摄现场照片并保存了。

       有了照片,接下来就是找到并加载它,然后展示给用户看。在南昌APP开发的技术实现上,这需要加载照片到大小合适的Bitmap对象中。要从文件生成Bitmap对象,我们需要BitmapFactory类:
       Bitmap bitmap = BitmapFactory.decodeFile(mPhotoFile.getPath());

       看到这里,有没有感觉不对劲?肯定有的。问题在于:介绍Bitmap时,我们提到“大小合适”。Bitmap是个简单对象,它只存储实际像素数据。也就是说,即使原始照片已压缩过,但存入Bitmap对象时,文件并不会同样压缩。因此,16万像素24位已压缩为5Mb大小的JPG照片文件,一旦载入Bitmap对象,就会立即膨胀至48Mb大小!

       这其实个问题是可以设法解决的,但需要手工缩放位图照片。具体做法就是,首先确认文件到底有多大,然后考虑按照给定区域大小合理缩放文件。最后,重新读取缩放后的文件,创建Bitmap对象。

       创建名为PictureUtils.java的新类,并在其中添加getScaledBitmap(String, int, int)缩放方法,如下代码清单所示。

       创建getScaledBitmap(...)方法(PictureUtils.java)
       public class PictureUtils {
       public static Bitmap getScaledBitmap(String path, int destWidth, int destHeight) {
       // Read in the dimensions of the image on disk
       BitmapFactory.Options options = new BitmapFactory.Options();
       options.inJustDecodeBounds = true;
       BitmapFactory.decodeFile(path, options);

       float srcWidth = options.outWidth;
       float srcHeight = options.outHeight;
 
       // Figure out how much to scale down by
       int inSampleSize = 1;
       if (srcHeight > destHeight || srcWidth > destWidth) {
       if (srcWidth > srcHeight) {
       inSampleSize = Math.round(srcHeight / destHeight);
       } else {
       inSampleSize = Math.round(srcWidth / destWidth);
       }
       }

       options = new BitmapFactory.Options();
       options.inSampleSize = inSampleSize;
       // Read in and create final bitmap
       return BitmapFactory.decodeFile(path, options);
       }
       } 

       上述方法中,inSampleSize值很关键。它决定着缩略图像素的大小。假设这个值是1的话,就表明缩略图和原始照片的水平像素大小一样。如果是2的话,它们的水平像素比就是1∶2。因此,inSampleSize值为2时,缩略图的像素数就是原始文件的四分之一。

       问题总是接踵而来,解决了缩放问题,又冒出了新问题:fragment刚启动时,PhotoView
       究竟有多大无人知道。onCreate(...)、onStart()和onResume()方法启动后,才会有实例化布局出现。也就在此时,显示在屏幕上的视图才会有大小尺寸。这也是出现新问题的原因。

       解决方案有两个:要么等布局实例化完成并显示,要么干脆使用保守估算值。特定条件下,尽管估算比较主观,但确实是一个切实可行的办法。再添加一个getScaledBitmap(String,Activity)静态Bitmap估算方法,如下代码所示。

       编写合理的缩放方法(PictureUtils.java)
       public class PictureUtils {
       public static Bitmap getScaledBitmap(String path, Activity activity) {
       Point size = new Point();
       activity.getWindowManager().getDefaultDisplay()
       .getSize(size);
       return getScaledBitmap(path, size.x, size.y);
       }
       ... 

       该方法先确认屏幕的尺寸,然后按此缩放图像。这样,就能保证载入的ImageView永远不会过大。看到没有,无论如何,这是一个比较保守的估算有时就是能解决问题。

       接下来,为把Bitmap载入ImageView。在CrimeFragment.java中,添加刷新mPhotoView的方法,如下代码清单所示。
       更新mPhotoView(CrimeFragment.java)
       ...
       private String getCrimeReport() {
       ...
       }
       private void updatePhotoView() {
       if (mPhotoFile == null || !mPhotoFile.exists()) {
       mPhotoView.setImageDrawable(null);
       } else {
       Bitmap bitmap = PictureUtils.getScaledBitmap(
       mPhotoFile.getPath(), getActivity());
       mPhotoView.setImageBitmap(bitmap);
       }
       }
       } 

       然后,分别在onCreateView(...)和onActivityResult(...)方法中调用updatePhotoView()
       方法,如下代码清单所示。

       调用updatePhotoView()方法(CrimeFragment.java)
       mPhotoButton.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
       startActivityForResult(captureImage, REQUEST_PHOTO);
       }
       });
       mPhotoView = (ImageView) v.findViewById(R.id.crime_photo);
       updatePhotoView();
       return v;
       }
       @Override
       public void onActivityResult(int requestCode, int resultCode, Intent data) {
       if (resultCode != Activity.RESULT_OK) {
       return;
       }
       if (requestCode == REQUEST_DATE) {
       ...
       } else if (requestCode == REQUEST_CONTACT && data != null) {
       ...
       } else if (requestCode == REQUEST_PHOTO) {
       updatePhotoView();
       }
       } 

       再次运行应用,这样就可以看到已拍照片的缩略图了。
400-680-9298,0791-88117053
扫一扫关注百恒网络微信公众号

欢迎您的光顾,我们将竭诚为您服务×

售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售后服务 售后服务
 
备案专线 备案专线
 
售后服务 售后服务
 
×