`
dengyin2000
  • 浏览: 1225499 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Androidr的图片的缩放、读取、压缩保存

阅读更多
最近这几天一直在做一个画报的app, 需要有大量的图片来展示, 而且这些图片都是很大一张的1200×1200, 本来想用sampleSize来缩放图片, 但是因为sample size最少也要压缩2倍, 担心图片的质量会大差,后来终于找到网上的一段代码来计算这个sampleSize, 听说是google自己的代码。这里的minSideLength 为-1, 而maxNumOfPixels参数的值  如果是宽高都是400的话  就应该填400*400*4后面为什么乘四? 因为一个像素占四个字节。 我也是看到这篇文章上说的。 这样会动态计算出一个最合适sample。

http://yangguangfu.iteye.com/blog/1050445


 
  public static int computeSampleSize(BitmapFactory.Options options,
                                        int minSideLength, int maxNumOfPixels) {
        int initialSize = computeInitialSampleSize(options, minSideLength,maxNumOfPixels);

        int roundedSize;
        if (initialSize <= 8 ) {
            roundedSize = 1;
            while (roundedSize < initialSize) {
                roundedSize <<= 1;
            }
        } else {
            roundedSize = (initialSize + 7) / 8 * 8;
        }

        return roundedSize;
    }

    private static int computeInitialSampleSize(BitmapFactory.Options options,int minSideLength, int maxNumOfPixels) {
        double w = options.outWidth;
        double h = options.outHeight;

        int lowerBound = (maxNumOfPixels == -1) ? 1 :
                (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
        int upperBound = (minSideLength == -1) ? 128 :
                (int) Math.min(Math.floor(w / minSideLength),
                        Math.floor(h / minSideLength));

        if (upperBound < lowerBound) {
            // return the larger one when there is no overlapping zone.
            return lowerBound;
        }

        if ((maxNumOfPixels == -1) &&
                (minSideLength == -1)) {
            return 1;
        } else if (minSideLength == -1) {
            return lowerBound;
        } else {
            return upperBound;
        }
    }



引用
在开发图片浏览器等软件是,很多时候要显示图片的缩略图,而一般情况下,我们要将图片按照固定大小取缩略图,一般取缩略图的方法是使用 BitmapFactory的decodeFile方法,然后通过传递进去 BitmapFactory.Option类型的参数进行取缩略图,在Option中,属性值inSampleSize表示缩略图大小为原始图片大小的几 分之一,即如果这个值为2,则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4。
  然而,如果我们想取固定大小的缩略 图就比较困难了,比如,我们想将不同大小的图片去出来的缩略图高度都为200px,而且要保证图片不失真,那怎么办?我们总不能将原始图片加载到内存中再 进行缩放处理吧,要知道在移动开发中,内存是相当宝贵的,而且一张100K的图片,加载完所占用的内存何止 100K?
  经过研究,发现,Options中有个属性inJustDecodeBounds,研究了一下,终于明白是什么意思了,SDK中的E文是这么说的
   If set to true, the decoder will return null (no bitmap), but the out... fields will still be set, allowing the caller to query the bitmap without having to allocate the memory for its pixels.
  意思就是说如果该值设为 true那么将不返回实际的bitmap不给其分配内存空间而里面只包括一些解码边界信息即图片大小信息,那么相应的方法也就出来了,通过设置 inJustDecodeBounds为true,获取到outHeight(图片原始高度)和 outWidth(图片的原始宽度),然后计算一个inSampleSize(缩放值),然后就可以取图片了,这里要注意的是,inSampleSize 可能小于0,必须做判断。
具体代码如下:
FrameLayout fr=(FrameLayout)findViewById(R.id.FrameLayout01);
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/test.jpg", options); //此时返回bm为空
        options.inJustDecodeBounds = false;
         //缩放比
        int be = (int)(options.outHeight / (float)200);
        if (be <= 0)
            be = 1;
        options.inSampleSize = be;
        //重新读入图片,注意这次要把options.inJustDecodeBounds 设为 false哦
        bitmap=BitmapFactory.decodeFile("/sdcard/test.jpg",options);
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        System.out.println(w+"   "+h);
        ImageView iv=new ImageView(this);
        iv.setImageBitmap(bitmap);
这样我们就可以读取较大的图片而不会内存溢出了。如果你想把压缩后的图片保存在Sdcard上的话就很简单了:
File file=new File("/sdcard/feng.png");
        try {
            FileOutputStream out=new FileOutputStream(file);
            if(bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)){
                out.flush();
                out.close();
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

ok,这样就把图片保存在/sdcard/feng.png这个文件里面了,呵呵。

但是这里的缩放保存是按长宽比例的,下边也可以按固定大小缩放哦:

        int bmpWidth  = bitmap.getWidth(); 

        int bmpHeight = bitmap.getHeight(); 

         

        //缩放图片的尺寸 

        float scaleWidth  = (float) sWidth / bmpWidth;     //按固定大小缩放  sWidth 写多大就多大

        float scaleHeight = (float) sHeight / bmpHeight;  //

        Matrix matrix = new Matrix(); 

        matrix.postScale(scaleWidth, scaleHeight); 

         

        //产生缩放后的Bitmap对象 

        Bitmap resizeBitmap = Bitmap.createBitmap( 

            bitmap, 0, 0, bmpWidth, bmpHeight, matrix, false); 

        bitmap.recycle(); 

                Bitmap resizeBitmap = bitmap; 

        //Bitmap to byte[] 

        byte[] photoData = bitmap2Bytes(resizeBitmap); 

       

        //save file 

        String fileName = "/sdcard/test.jpg"; 

        FileUtil.writeToFile(fileName, photoData);



引用
压缩图片质量:    
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, fos);    
其中的quality为0~100, 可以压缩图片质量, 不过对于大图必须对图片resize   
 
这个是等比例缩放: 
bitmap = Bitmap.createScaledBitmap(bitmap, width, height, false); 
 
这个是截取图片某部分: 
bitmap = Bitmap.createBitmap(bitmap, x, y, width, height); 
 
这几个方法都是针对Bitmap的, 不过鉴于Bitmap可以从file中读取, 也可以写入file.   
 
这是我知道Android自带库里中唯一可以缩放和压缩的图片方法. 
分享到:
评论

相关推荐

    Android图片的压缩与缓存

    本篇将深入探讨Android图片的压缩与缓存机制,以提高应用性能并防止内存溢出。 ### Bitmap对象与内存管理 Bitmap是Android中用于表示图像数据的类,它直接占用大量的内存资源。当加载大尺寸图片时,未进行适当处理...

    Android图片读取.rar

    在Android应用开发中,图片的读取是一项基本且重要的任务,尤其在如今视觉元素丰富的移动应用中。Android Studio是Google官方推荐的集成开发环境(IDE),用于构建Android应用程序。在这个"Android图片读取"的压缩包...

    Android从图库加载图片并实现多选效果

    - 多选图片后,你需要一个数据结构(如List)来保存所有选中的图片URI或压缩后的图片数据。 - 可以考虑使用`SparseArray`或者自定义类来存储图片信息,包括URI、压缩后的图片数据等。 6. **显示预览** - 将选中...

    edittext输入图片和文字

    在Android中,为了节省内存和提高加载速度,图片通常需要进行压缩。我们可以使用BitmapFactory.Options对象来控制解码时的缩放比例,以及设置inPreferredConfig为ARGB_8888或RGB_565以降低位深度。以下是一个简单的...

    android图片与内存的关系

    例如,使用`android:background="@drawable/hdpi"`在XML布局文件中设置背景图片,或者通过`Resources.getDrawable(R.drawable.hdpi)`在代码中获取图片资源。这些方法最终都会转化为`Drawable`对象,而`Drawable`是一...

    使用ImageLoader进行图片加载

    2. 磁盘缓存:图片会被保存在设备的外部存储空间,即使应用关闭,下次加载时也能从磁盘读取,减少了网络请求。 3. 图片压缩:在加载图片时,ImageLoader可以自动调整图片大小,避免加载原图导致的内存占用过高。 在...

    Android ImageSwitch

    3. **图片处理**:在Android中,高效处理图片是关键,ImageSwitch可能采用了内存缓存和磁盘缓存策略来避免频繁的IO操作,同时可能使用了Bitmap的缩放和压缩技术以节省内存。比如,使用`BitmapFactory.Options`来控制...

    调用相机相册获取图片bitmap,转化成base64

    `handleSelectedImage`方法中,我们首先获取图片的路径,然后读取图片并转换为Bitmap: ```java private void handleSelectedImage(Uri selectedImageUri) { try { ParcelFileDescriptor parcelFileDescriptor = ...

    SD卡,本地资源,网络图片的加载,使用缓存机制,防止OOM

    磁盘缓存则长期保存图片,即使应用关闭,下次启动仍能快速加载。缓存策略还包括根据图片尺寸、分辨率进行动态调整,避免加载不必要的大图。 在实际开发中,还需注意以下几点: 1. 使用适当的图片格式:JPEG适合...

    加载本地图片

    "加载本地图片"这个主题涉及到如何有效地读取和展示存储在设备上的图片,同时避免内存溢出(Out Of Memory,简称OOM)问题。以下是关于这个主题的详细知识点: 1. 图片资源类型: - JPEG:适用于照片或包含大量...

    加载图片显示

    7. **动画效果**: 图片加载库通常支持图片加载和显示的动画效果,如淡入淡出、缩放等,以增加界面的动态感。 8. **异步加载**: 图片加载通常在后台线程进行,以防止阻塞UI主线程,保证应用流畅性。Android的...

    安卓实现图片从相册中获取

    这不仅包括了图片的选取,还包括了图片的读取、缩放以及显示。在实际开发中,可能还需要考虑图片的裁剪、压缩等优化操作,以适应不同场景的需求。同时,要确保遵循最佳实践,如使用`AsyncTask`或` Glide`库异步加载...

    Android开发之加载图片的方法

    在使用`AsyncTask`加载网络图片时,还可以同时保存图片到本地,以便后续使用时能快速加载。这可以通过读取`InputStream`并将其写入本地文件来实现。例如: ```java // 在doInBackground()方法中 FileOutputStream ...

    拍照并在当前界面显示图片

    在实际开发中,我们可能还需要对图片进行一些处理,比如裁剪、压缩、调整大小等,以适应不同的显示需求或上传限制。这通常涉及到`Bitmap`对象的进一步操作,例如使用`Bitmap.createScaledBitmap()`进行缩放,或者...

    GridView加载sd卡图片.zip

    为了避免内存溢出,可以使用BitmapOptions的inJustDecodeBounds参数预读取图片尺寸,然后根据屏幕尺寸计算缩放比例。最后,使用ImageView显示Bitmap。 ```java Bitmap bitmap = BitmapFactory.decodeFile(file....

    Android Drawable、Bitmap、byte、灰度 之间的转换

    在Android开发中,图片资源的处理是常见的需求之一,尤其涉及到不同格式间的转换,如Drawable、Bitmap、byte数组以及灰度图像的转换。这些转换在实际应用中具有重要意义,不仅能够优化内存使用,还能实现图像的高效...

    android中的Bitmap相关[归类].pdf

    - 可以通过URL连接获取网络图片,首先创建URL对象,然后打开连接并获取输入流,最后通过`BufferedInputStream`读取数据。例如: ```java String icoURI = "http://202.140.96.134:8080/FS-RSS/img/RN.png"; URL ...

    android画图总结.pdf

    ### Android画图技术详解 #### 一、概述 在Android应用开发中,图像处理是非常重要的一个环节。无论是简单的UI设计还是复杂的游戏开发,都需要用到各种各样的图像处理技术。本文将详细介绍Android画图技术的核心...

    从模块中获取图标的资源

    在Android开发中,我们可以通过`R.drawable`来引用XML资源文件中的图标。 3. **处理和显示**:加载图标后,可能需要进行一些处理,如缩放、转换格式等,以便适应不同的设备或界面需求。在许多情况下,可以直接将...

    加载位图为背景.rar

    需要注意的是,由于位图文件可能较大,加载时要考虑到性能和内存占用,合理地进行压缩、缩放或使用适当的解码方式。此外,根据不同的平台和库,可能还需要处理颜色空间转换、透明度支持等问题。在实际开发中,确保对...

Global site tag (gtag.js) - Google Analytics