Android 加载超大长图及原理
Android 加载超大长图及原理
我们在开发中偶尔会遇到加载超大长图,类似于微信n多页聊天记录截图加载。但这类图片一般都会很大,几兆、十几兆、甚至几十兆,很容易造成内存溢出,今天笔者给大家提供一个可以满足此类需求的简单的自定义view。具体原理就是图片缩放,只加载屏幕显示区域图片,内存复用。代码很简单,注视也很相信,可以拿来直接用。
public class BigView extends View implements GestureDetector.OnGestureListener,View.OnTouchListener {private Scroller mScroll;//手势private GestureDetector mGestureDetector;private BitmapFactory.Options mOptions;private int mImageHeight;private int mImageWidht;//手机屏幕宽高private int mViewHeight;private int mViewWidth;//图片缩放因子private float mScale;private Rect mRect;private Bitmap mBitmap;//bitmap解码器private BitmapRegionDecoder mDecoder;public BigView(Context context) {this(context,null);}public BigView(Context context, AttributeSet attrs) {this(context, attrs,0);}public BigView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mOptions=new BitmapFactory.Options();//内存复用mGestureDetector=new GestureDetector(context,this);mScroll =new Scroller(context);mRect=new Rect();setOnTouchListener(this);}public void setImage(InputStream inputStream){//只将大图的边框加载到内存mOptions.inJustDecodeBounds=true;//将图片边宽加载到optionsBitmapFactory.decodeStream(inputStream,null,mOptions);mImageHeight=mOptions.outHeight;mImageWidht=mOptions.outWidth;//设置内存可复用mOptions.inMutable=true;//设置图片编码格式mOptions.inPreferredConfig=Bitmap.Config.RGB_565;mOptions.inJustDecodeBounds=false;try {//解码图片mDecoder= BitmapRegionDecoder.newInstance(inputStream,false);} catch (IOException e) {e.printStackTrace();}//requestLayout方法会导致View的onMeasure、onLayout、onDraw方法被调用;requestLayout();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mViewHeight=getMeasuredHeight();mViewWidth=getMeasuredWidth();mScale=mViewWidth/(float)mImageWidht;//等比例缩放后图片所占区域mRect.top=0;mRect.left=0;mRect.right= mImageWidht;mRect.bottom= (int) (mViewHeight/mScale);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if(mDecoder==null)return;//内存复用,分配空间mOptions.inBitmap=mBitmap;//指定解码区域mBitmap=mDecoder.decodeRegion(mRect,mOptions);Matrix matrix=new Matrix();//将图片缩放到手机屏幕内matrix.preScale(mScale,mScale);canvas.drawBitmap(mBitmap,matrix,null);}@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {//将触摸时间分发给手势return mGestureDetector.onTouchEvent(motionEvent);}@Overridepublic boolean onDown(MotionEvent motionEvent) {//当按下屏幕时,如果正在滑动,则强制停止滑动if(!mScroll.isFinished()){mScroll.forceFinished(true);}return true;}@Overridepublic boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {//滑动时rect偏移量计算mRect.offset(0, (int) v1);if(mRect.bottom>mImageHeight){mRect.bottom=mImageHeight;mRect.top=mImageHeight-(int)(mViewHeight/mScale);}if(mRect.top<0){mRect.top=0;mRect.bottom=(int)(mViewHeight/mScale);}//调用ondraw方法invalidate();return false;}@Overridepublic boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {mScroll.fling(0,mRect.top,0,(int)-v1,0,0,0,mImageHeight-(int)(mViewHeight/mScale));return false;}//处理滚动结果@Overridepublic void computeScroll() {if(mScroll.isFinished())return;if(mScroll.computeScrollOffset()){mRect.top=mScroll.getCurrY();mRect.bottom=mScroll.getCurrY()+(int)(mViewHeight/mScale);//调用ondraw方法invalidate();}super.computeScroll();}@Overridepublic void onShowPress(MotionEvent motionEvent) {}@Overridepublic boolean onSingleTapUp(MotionEvent motionEvent) {return false;}@Overridepublic void onLongPress(MotionEvent motionEvent) {}}
外部只需要简单调用即可使用 bigView.setImage(inputStream);
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);BigView bigView=findViewById(R.id.bigView);InputStream inputStream= null;try {inputStream = getAssets().open("big.jpeg");bigView.setImage(inputStream);} catch (IOException e) {e.printStackTrace();}}
}
Android 加载超大长图及原理相关推荐
- android 加载大长图,android加载长图片的方法
1.很多应用都有加载一张长图片,用户可以上下拉动图片. 自己没有好的想法,那只好百度咯.结果都说用webview来实现,好吧那就只好先试一下了. 2.自己写了简单的html,然后webview加载.图 ...
- android 加载类似长微博的超长图或超大图subsampling-scale-image-view
超长图直接加载的时候有可能会出现超出Bitmap最大高度,直接使用BitmapFactory.Options来缩放图片可能会把图片缩的太小,所以加载长图最好还是用BitmapRegionDecoder ...
- android 加载外部矢量图SVG
转自:http://blog.csdn.net/jiabailong/article/details/53736689 android加载矢量图的方式主要有以下两种: 一.Web方式 利用WebVIe ...
- android 展示大图,Android 加载超大图(原图)分析
众所周知,Android的ImageView不支持加载大图(高分辨率),会直接报错,如果不是特别大的图片,也可以选择使用WebView来加载,并且直接可以实现手势方法缩小平移等效果,但是如果图片特别长 ...
- Android 图片预览器加载微博长图,大图
通常图片预览的做法是ViewPager+PhotoView,但是遇到很长的图(比如微博长图),在设置 android:scaleType="centerCrop" 这个属性的前提下 ...
- Glide加载大图长图
这里用的Glide是4.11.0的 第一种方法: Glide.with(activity).load(yourUrl).asBitmap().into(new SimpleTarget<Bitm ...
- android 漫画加载方案,Android加载长图的多种方案分享
背景介绍 在某些特定场景下,我们需要考虑加载长图的需求,比如加载一幅<清明上河图>,这个好像有点过分了,那就加载1/2的<清明上河图>吧... 那TMD还不是一样道理. 言归正 ...
- Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)【系列1】...
Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)[系列1] Android在加载或者处理超大巨 ...
- Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)【系列1】
Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)[系列1] Android在加载或者处理超大巨 ...
最新文章
- BeautifulSoup_第二节
- python3.7.2下载-Python编程神器 v3.7.2 最新免费版
- iis php 图片无法显示,iis php 图片无法显示怎么办
- 动态的添加和丢弃关键点---32
- C# TreeNode的使用方法
- java获取当前电脑的ip_使用Java获取当前计算机的IP地址
- Python+OpenCV:图像Harris角点检测(Harris Corner Detection)
- 两边双虚线是什么意思_锯齿车道、倒三角标志什么意思?以下5种交通标线你认识几个?...
- 扎堆出海的抖音、今日头条、UC 头条们后来怎么样了?
- Storm并发度详解(转载)
- 金山卫士界面源码解读及界面库分离(4)
- 组合数学6--母函数与递推关系
- python(输入)正常返回否则出错重新
- Matlab GUI编程技巧(八):uitoolbar在图窗中创建工具栏
- 利用计算机模拟人类的活动属于,赠书 | 计算机能模拟人类心智吗?
- C++助教篇3_Week2不完全知识点
- python调用大漠插件寻路_python怎么调用大漠?
- vue项目获取下拉框选中id_vue获取下拉框值
- UE4 如何旋转模型骨骼
- ZOJ3587 Marlon's String
热门文章
- 用HashSet/Random写摇号器(数字不重复、无序)
- Mendix之REST服务详解
- 【Unity特效】LWRP/URP(Lightweight RP/Universal RP)和ShaderGraph下载及安装配置
- mysql中拼音排序的方法_mysql的中文数据按拼音排序的2个方法
- 微创业计划PPT模板
- 正则表达式基本字符含义
- python+pytest接口自动化(1)-接口测试基础
- 第二课作业(刘萌150206318)
- 机器学习基础01-线性代数
- vue+ts中引入组件自动提示 declare module