当前位置:阳光沙滩 >Android > 查看文章

把普通的小图片加载到内存

在看这文章之前,推荐你看的文章是:
图片大小的计算,看完之后呢,你将知道图片的存储方式和这个大小的计算方式。
OK,进入正题在安卓开发中,用到图片是必须的嘛,怎么样把这个图片加载到内存中呢?
很简单:通过位图工厂就可以了!
1、首先我把一张图片导入到这个SD卡里头。开启模拟器(AVD:android vitual Device)
点击Eclipse里的DDMS,—— 然后向mmt/sdcard下导入一张图片:
%e5%9b%be%e7%89%8717
注意的地方:
1、图片不要太大哦。100K以内就好
2、图片不能有中文,要不就不能导入了
 
OK,有了图片,就开始写代码吧。先把界面弄一下,很简单,只需要一个ImageView即可。
<ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/iv_pic" />
编写MainActivity的代码
package com.sunofbeaches.loadpic;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;

public class MainActivity extends Activity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);

                // 定义出图片的路径
                String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/1412225924.jpg";
                                
                // 利用位图工厂获加载位图到内存中
                Bitmap bitmap = BitmapFactory.decodeFile(path);

                // 让图片控件显示一下,看是否有加载成功!
                ImageView iv_pic = (ImageView) findViewById(R.id.iv_pic);
                iv_pic.setImageBitmap(bitmap);
        }
}

运行结果:

%e5%9b%be%e7%89%8724

好,这样呢,这个图片就是加载成功了的,但相信大家也注意到了,前面我一真提到这个图片的大小不要太大。为什么呢?

因为接下来我们就要演示一下这个大图片的加载了!

1.安卓中加载大图片到内存中

对于大图片的加载,如果和上面一样,那么内存会不够用的,先做实验吧!我们把一张大的图片导入到这个SD卡下。然后跟上面一样的方式编写代码。界面的代码一样。我导入的图片大小为:4.86 MB (5,096,597 字节)

修改了这里!

// 定义出图片的路径
String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/touxiang.jpg";

%e5%9b%be%e7%89%8734

图片大小是2736*3648=3097640,在安卓中,图片是以32位的形式保存的。也就是每一个像素点32位。8位表示alpha,8位表示Red,8位表示Green,8位表示Blue

也就是上面这个大小的图片大小为3097640*32/8=39923712Byte=38988KB=38.07421875M,而我们的模拟器一个应用程序最多支持16M,当然,这个可以自行设置,不过最好和真机一样。在实际做开发中呢,用的也是真机。

%e5%9b%be%e7%89%8744

所以呢,就报这个内存异常了。那到底怎么样才能解决这个问题呢?这里我们需要用到一个方法了。
来……,我们小手一抖,把代码写一下。
package com.sunofbeaches.loadpic;

import java.io.IOException;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.media.ExifInterface;
import android.os.Bundle;
import android.os.Environment;
import android.view.Display;
import android.view.WindowManager;
import android.widget.ImageView;

public class MainActivity extends Activity {

        @SuppressWarnings("deprecation")
        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);

                // 2、从后面逆推回来的,我们需要这个图片的路径
                String pathName = Environment.getExternalStorageDirectory()
                                .getAbsolutePath() + "/touxiang.jpg";

                // 4、获取屏幕与图片的比例值
                        // a)通过服务获取到这个屏幕的管理者
                        WindowManager windowManager = (WindowManager) this
                                        .getSystemService(WINDOW_SERVICE);
                        /*
                         * Provides information about the size and density of a logical display.
                         * Display 提供关于本地显示器的尺寸和比例
                         */
                        Display display = windowManager.getDefaultDisplay();
        
                        int displayHeight = display.getHeight();// 获取屏幕的高度
                        int displayWidth = display.getWidth();//获取屏幕宽度
                        String imageWidth = null;
                        String imageLength = null;
                        
        
                        // 获取到这个图片的尺寸
                        try {
                                ExifInterface exifInterface = new ExifInterface(pathName);// 传入这个图片的路径
                                imageWidth = exifInterface
                                                .getAttribute(ExifInterface.TAG_IMAGE_WIDTH);
                                imageLength = exifInterface
                                                .getAttribute(ExifInterface.TAG_IMAGE_LENGTH);
                        } catch (IOException e) {
                                e.printStackTrace();
                        }
                        
                        //获取比例值
                int proportionW = Integer.parseInt(imageWidth)/displayWidth;
                int proportionH = Integer.parseInt(imageLength)/displayHeight;
                
//                int result = proportionH>proportionW?proportionH:proportionW;
        int result = (proportionH+proportionW)/2;
                // 3、这个选项,我们就造一个呗!
                Options opts = new Options();
        
                opts.inSampleSize = result;// 假设这里是4那么这里的采样将会是原来的4分之1.这怎么回事呢
                // 假设之前的图片的宽为1000像素,那么显示时的采样宽度为250个像素。
                // 当然,这个大不是写死的,一般我们要获取到这个屏幕的宽度,或者高度,再获取这个图片的宽度或者高度
                // 获取两者之间的比例值,取大的那个作为这个inSampleSize的值。所以这里又逆推回去了,获取比例值.

                // 1、加载图片到内存中,还是使用这个图片工厂,有一个重载的方法
                /**
                 * 两个参数的解释 
                 * -------------------------------------- 
                 * pathName complete path
                 * name for the file to be decoded. 
                 * 被解码的完整路径(也就是图片的路径)
                 * --------------------------------------- 
                 * opts null-ok; Options that
                 * control downsampling and whether the image should be completely
                 * decoded, or just is size returned. 
                 * 控制向下采样或者这个图片是否被完整解码或者只是返回大小的选项
                 * 也就是控制这个图片的采样率
                 */
                Bitmap bitmap = BitmapFactory.decodeFile(pathName, opts);// 由这里逆推回
                
                //5、最后一步,让控件显示一下图片
                ImageView iv_img = (ImageView) findViewById(R.id.iv_pic);
                iv_img.setImageBitmap(bitmap);
        }
}

结果是怎么样的呢?

当然是成功的嘛,哈哈,如图所示!
%e5%9b%be%e7%89%8754
如果大家发现这样一个问题:本来这个图片在电脑上看的时候是竖着的,但是加载到这个手机内存上,再用ImageView查看时,是躺着,横折的,那么这是什么问题呢?
是这样的,你这图片可能是用数码相机拍摄的,这种Exif格式也就是jpg格式的图片呢,在头部写有很多跟这个相机相关的信息,在电脑上看的时候,软件会识别出来,但在这个安卓系统中,这信息就识别不出来了。所以就躺啦,哈哈!知道就好!
解决方法:
1、用我们后面讲到的动画,补间动画,对图片进行操作,搞一个矩阵旋转就可以了。
2、可以用Photoshop等图片处理软件处理一下。

 

7K
为您推荐
各种观点