Android 加载长图

如果说让你加载一个类似微博那样的长图,你可能会想ScrollView里面套一个ImageView

mImageView.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.bg));

那么运行你的代码结果就是:




所以此方法是不行不行的

我的解决方法:

java.lang.Object  
        ↳android.graphics.BitmapRegionDecoder

类描述:

BitmapRegionDecoder类用来编译(解码)在图片内不同的方形区域,BitmapRegionDecoder类在使用较大图片只需要取得图片中的一小部分的内容是特别有效益的。

public Bitmap decodeRegion (Rect rect, BitmapFactory.Options options)

解码该图片的一个矩形区域,该区域由rect决定,返回值为显示图像为该区域的bitmap,注意options中不能使用inPurgeable这个参数

public int getHeight ()
public int getWidth ()

获取原图片的宽和高

public final boolean isRecycled ()

判断该对象是否被回收利用,如果是,那么调用它的方法会报错

public static BitmapRegionDecoder newInstance (String pathName, boolean isShareable)

用于创建BitmapRegionDecoder,pathName表示路径,只有jpeg和png图片才支持这种方式,isShareable如果为true,那BitmapRegionDecoder会对输入流保持一个表面的引用,如果为false,那么它将会创建一个输入流的复制,并且一直使用它。即使为true,程序也有可能会创建一个输入流的深度复制。如果图片是逐步解码的,那么为true会降低图片的解码速度。如果路径下的图片不是支持的格式,那就会抛出异常

public static BitmapRegionDecoder newInstance (InputStream is, boolean isShareable)

同上,不过参数is变成了输入流

public static BitmapRegionDecoder newInstance (FileDescriptor fd, boolean isShareable)

同上,不过参数变成了文件描述符,在函数运行完之前,文件描述符不可以改变

public static BitmapRegionDecoder newInstance (byte[] data, int offset, int length, boolean isShareable)

同上,不过参数变成了字节数组,offset为起始位置,length为长度

InputStream is = getResources().openRawResource(R.drawable.bg);  
            mDecoder = BitmapRegionDecoder.newInstance(is, true); 
              
            final int imgWidth = mDecoder.getWidth();  
            final int imgHeight = mDecoder.getHeight();  
              
            mRect.set(0, 0, imgWidth, imgHeight);  
            Bitmap bm = mDecoder.decodeRegion(mRect, null); 
//            BitmapFactory.Options opts = new BitmapFactory.Options(); 
//            Bitmap bm = mDecoder.decodeRegion(mRect, opts); 
            mImageView1.setImageBitmap(bm); 
仅仅这样就把整张图片显示出来了

然后我就怀疑了,网上很多说长图要用BitmapRegionDecoder切图的,那么为什么我没切就把整张图加载出来了呢

所以我把图从3500像素加长到8000像素了,果然,,



解决办法:切图用图高/4096+1个imageview显示,这里我没那么精确,用了三个imageview

public class MainActivity extends Activity {
	private final Rect mRect = new Rect();
	private BitmapRegionDecoder mDecoder;
	private ImageView mImageView1, mImageView2, mImageView3;
	private DisplayMetrics dm;
	private int screenHeight;
	private int screenWidth;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		dm = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(dm);
		screenHeight = dm.heightPixels;
		screenWidth = dm.widthPixels;
		Log.e("ee", "screenWidth:" + screenWidth + "    screenHeight:" + screenHeight);
		setContentView(R.layout.activity_main);
		mImageView1 = (ImageView) findViewById(R.id.im1);
		mImageView2 = (ImageView) findViewById(R.id.im2);
		mImageView3 = (ImageView) findViewById(R.id.im3);
		try {
			InputStream is = getResources().openRawResource(R.drawable.bg);
			mDecoder = BitmapRegionDecoder.newInstance(is, true);

			final int imgWidth = mDecoder.getWidth();
			final int imgHeight = mDecoder.getHeight();
			Log.e("ee", "imgWidth:" + imgWidth + "    imgHeight:" + imgHeight);
			BitmapFactory.Options opts = new BitmapFactory.Options();
			
			mRect.set(0, 0, imgWidth, 3000);
			Bitmap bm = mDecoder.decodeRegion(mRect, opts);
			mImageView1.setImageBitmap(bm);

			mRect.set(0, 3000, imgWidth, 2 * 3000);
			Bitmap bm1 = mDecoder.decodeRegion(mRect, opts);
			mImageView2.setImageBitmap(bm1);

			mRect.set(0, 6000, imgWidth, 8000);
			Bitmap bm2 = mDecoder.decodeRegion(mRect, opts);
			mImageView3.setImageBitmap(bm2);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}
其中在解决问题的过程中遇到问题:图片不显示

是因为Bitmap bm = mDecoder.decodeRegion(mRect, opts);第二个参数看网上都传的null,所以我开始也传的null,所以图片一直加载不出来

还有一点需要注意:

mRect.set(left, top, right, bottom)的第四个参数,也就是右下角左边,也就是图片的高不能大于这里的4096,我用4096试了一下能加载出图片,换成4097就不行了。




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值