Giter VIP home page Giter VIP logo

ximageview's Introduction

XImageView

XImageView 可以显示超大尺寸的图片, 并支持缩放,双击放大, 拖动,单击,长按等手势操作, 支持惯性滑动, 支持ViewPager

欢迎使用

demo

这是一张 21250 x 7500 (1亿6千万像素)像素(121 MB), 加载需要30s 左右

这里可以下载这些大图 http://pan.baidu.com/s/1mhw6Qko

Usage

dependencies {
    compile 'cn.kejin.ximageview:XImageView:1.2.2'
}
<cn.kejin.ximageview.XImageView
	android:id="@+id/xImageView"
	android:layout_height="match_parent"
	android:layout_width="match_parent"
    app:initType="fitViewMinImageMin"
    app:doubleType="fitImageMinViewMax"/>
<!-- initFitView 属性是当图片小于 view的尺寸时,是否需要在初始化时使用view的尺寸 -->
try {
    mXImageView.setImage(getAssets().open("b.jpg"));
}
catch (IOException e) {
	e.printStackTrace();
}

Details

属性 说明
initType fitViewMin 默认为此类型 总是缩放适应View的最短的边长
fitViewMinImageMin 当图片的尺寸小于 view 的尺寸时, 不进行放大, 否则缩小至适应view的最短的边长
fitViewMax TODO: 尚未实现 总是缩放适应View的最长的边长
fitImage TODO: 尚未实现 图片有多大显示多大
doubleType fitViewMinViewMax 默认为此种类型 缩小至 ViewMin, 放大至 ViewMax
fitImageMinViewMax 缩小至 Min(viewMin, imageMin), 放大至 viewMax
fitViewMinImageMax TODO: 尚未实现 缩小至 viewMin, 放大至 Max(imageMax, Min(3 x imageMax, viewMax))
fitImageMinImageMax TODO: 尚未实现 缩小至 Min(viewMin, imageMin), 放大至 Max(imageMax, Min(3 x imageMax, viewMax))
/**
 * 初始化状态类型
 */
enum InitType {

    /**
     * 总是缩放到适应 view 的最小一边
     * 默认为这种类型
     */
    FIT_VIEW_MIN(1),

    /**
     * 总是缩放到适应 view 的最大一边
     */
    FIT_VIEW_MAX(2),

    /**
     * 图片有多大就显示多大
     */
    FIT_IMAGE(4),

    /**
     * 当图片小于 view 的最小边的时候, 不进行缩放, 按照 image 的尺寸显示,
     * 如果大于view 的最小边就缩放至适应 view 的最小边
     */
    FIT_VIEW_MIN_IMAGE_MIN(8)
}

/**
 * 双击缩放类型
 * 此处和 attrs.xml: doubleType 的value 保持一致
 */
enum DoubleType {
    /**
     * (默认为这种)
     * 缩小至 viewMin
     * 放大至 viewMax
     */
    FIT_VIEW_MIN_VIEW_MAX(1),

    /**
     * 缩小至 Min(viewMin, imageMin)
     * 放大至 viewMax
     */
    FIT_IMAGE_MIN_VIEW_MAX(2),

    /**
     * 缩小至 viewMin
     * 放大至 Max(imageMax, Min(3 x imageMax, viewMax))
     */
    FIT_VIEW_MIN_IMAGE_MAX(3),

    /**
     * 缩小至 Min(viewMin, imageMin)
     * 放大至 Max(imageMax, Min(3 x imageMax, viewMax))
     */
    FIT_IMAGE_MIN_IMAGE_MAX(4);
}

XImageView 支持使用FilePath, File, InputStream, Bitmap 来设置图片, FilePath, File 会转换为 InputStream, 在使用 Bitmap 设置图片时,要注意内存的消耗(因为内部会使用一个副本), 可以使用 setImage(bitmap, cache), 这个方法会把 Bitmap 转换为InputStream,再设置图片,不过这样会比较耗时!

void setImage(Bitmap bitmap)
void setImage(Bitmap bitmap, boolean cache);

// 默认的 Config 为 Bitmap.Config.RGB_565
void setImage(String path);
void setImage(String path, Bitmap.Config config);

void setImage(File file);
void setImage(File file, Bitmap.Config config);

void setImage(InputStream inputStream);
void setImage(InputStream is, Bitmap.Config config);
接口 说明
void setInitType(InitType type) 设置初始缩放类型
void setDoubleTapScaleType(DoubleType type) 设置双击缩放的缩放方式
void scaleImage(float dest, boolean smooth, int smoothTime); 以View的中心点为中心缩放, 缩放的目标倍数是以当前的显示的尺寸来计算的(比如 dest=1.1, 则会在当前的显示的基础上放大0.1倍)
void scaleImage(int cx, int cy, float dest, boolean smooth, int smoothTime) 以一点为中心缩放图片, (cx,cy) 中心点, dest 缩放的目标倍数,以当前的倍数来计算,smooth 是否使用动画, smoothTime 动画时间
void scaleToMaxFitView(int cx, int cy, boolean smooth, int smoothTime) 缩放到最大适应View(就是图片宽高 >= View的宽高)
void scaleToMinFitView(int cx, int cy, boolean smooth, int smoothTime) 缩放到最小适应View (就是图片宽高 <= View的宽高)
int scrollImage(int dx, int dy) 滑动图片, 返回当前已经到达的边界BitmapManager.NONE LEFT RIGHT TOP BOTTOM, (dx, dy) 相对滑动的像素, 当滑动这个图片,如果已经到达了左边的边界, 已经不能再继续向右滑动,则 scrollImage()LEFT, 如果这个图片左边和上边都已经不能继续滑动,则会返回 `LEFT
float getScaleFactor() 获取当前图片的缩放的倍数,相对图片的原始图片的尺寸来说的
Rect getRealImageRect() 获取真实图片的尺寸,注意最好在 onSetImageFinished() 之后获取这个值
Rect getShowImageRect() 获取当前图片显示出来的的尺寸
boolean isSettingImage() 判断是否正在设置图片

监听单击, 双击, 长按, 和 设置完成 事件, 如果需要监听onSetImageFinished(), 需要在setImage()之前设置这个监听

// 监听单击, 双击, 长按, 和 设置完成 事件
mXImageView.setActionListener(new XImageView.OnActionListener()
{
    @Override
    public void onSingleTapped(XImageView view, MotionEvent event, boolean onImage)
    {
    }

    @Override
    public boolean onDoubleTapped(XImageView view, MotionEvent event)
    {
        return false; // 返回 true 表示已经处理了双击事件, 不会进行缩放操作
    }

    @Override
    public void onLongPressed(XImageView view, MotionEvent event)
    {
    }

    @Override
    public void onSetImageFinished(XImageView view, boolean success, Rect image)
    {
    }
});

// 如果不想监听这么多, 可以使用 XImageView.SimpleActionListener

ximageview's People

Contributors

liungkejin avatar

Stargazers

YuriTam avatar  avatar ZhenHui-Li avatar brady2037 avatar  avatar UaoanLao avatar  avatar 夏洋洋 avatar Matt Yao avatar  avatar  avatar 余波 avatar  avatar  avatar Re. avatar  avatar shufeng.wu avatar  avatar  avatar Sam Wong avatar nowcoder-chenyangdong avatar  avatar  avatar Steven avatar NiceCoder avatar ANTASU avatar tanbiheng avatar YuPeng Zuo avatar Yafei.Chen avatar  avatar 三好先森 avatar  avatar mmdet avatar 水点冰 avatar 飞飞 avatar BOB avatar qingmei2 avatar  avatar  avatar bagelly avatar  avatar 杨明斌 avatar  avatar shaoyu0829 avatar  avatar 桥边落木 avatar  avatar emptykid avatar  avatar 王健 avatar  avatar Pranav Lathigara avatar bob.sun avatar JackWang avatar  avatar 土豆泥 avatar Kin Kaku avatar JasonZhang avatar Sendtion avatar  avatar  avatar LEO avatar zhaohan avatar Eddie avatar  avatar Ren  Yu avatar  avatar  avatar  avatar Kevin avatar  avatar  avatar JohnHuang avatar cornflower avatar  avatar 何悦 avatar Vincent avatar  avatar  avatar  avatar 李明艺 avatar chen chang song avatar dennis avatar 石朝辉 avatar  avatar

Watchers

James Cloos avatar  avatar Ren  Yu avatar Sendtion avatar  avatar  avatar  avatar ShawnPeng avatar  avatar

ximageview's Issues

重构代码

目前的代码可扩展性低,代码混乱, 功能小,且存在部分bug, 所以需要重构代码!

java.lang.OutOfMemoryError: Failed to allocate a 6160332 byte allocation with 2849520 free bytes and 2MB until OOM

java.lang.OutOfMemoryError: Failed to allocate a 6160332 byte allocation with 2849520 free bytes and 2MB until OOM at dalvik.system.VMRuntime.newNonMovableArray(VMRuntime.java) at android.graphics.Bitmap.nativeCreate(Bitmap.java) at android.graphics.Bitmap.createBitmap(Bitmap.java:859) at android.graphics.Bitmap.createBitmap(Bitmap.java:829) at android.graphics.Bitmap.createBitmap(Bitmap.java:740) at android.graphics.Bitmap.createBitmap(Bitmap.java:665) at cn.kejin.ximageview.BitmapManager.decodeRectBitmap(BitmapManager.java:646) at cn.kejin.ximageview.BitmapManager.access$100(BitmapManager.java:31) at cn.kejin.ximageview.BitmapManager.access$300(BitmapManager.java:31) at cn.kejin.ximageview.BitmapManager.access$400(BitmapManager.java:31) at cn.kejin.ximageview.BitmapManager.access$502(BitmapManager.java:31) at cn.kejin.ximageview.BitmapManager.access$900(BitmapManager.java:31) at cn.kejin.ximageview.BitmapManager.access$2500(BitmapManager.java:31) at cn.kejin.ximageview.BitmapManager.access$2800(BitmapManager.java:31) at cn.kejin.ximageview.BitmapManager.access$2900(BitmapManager.java:31) at cn.kejin.ximageview.BitmapManager.access$3302(BitmapManager.java:31) at cn.kejin.ximageview.BitmapManager$BitmapGrid.decodeThumbUnitBitmap(BitmapManager.java:1005) at cn.kejin.ximageview.BitmapManager$BitmapGrid.access$1800(BitmapManager.java:719) at cn.kejin.ximageview.BitmapManager$BitmapGrid$1.run(BitmapManager.java:765) at android.os.Handler.handleCallback(Handler.java:743) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:150) at android.os.HandlerThread.run(HandlerThread.java:61)

源码:
/**
* 解码出一块bitmap
*/
private Bitmap decodeRectBitmap(Rect rect, int sampleSize) {
if (rect == null || !mImageRect.contains(rect)) {
return null;
}

    synchronized (mBitmapLock) {
        if (mSrcBitmap != null) {

646行-这里报的oom----> return Bitmap.createBitmap(mSrcBitmap, rect.left, rect.top, rect.width(), rect.height());
} else if (mDecoder != null) {
BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
tmpOptions.inPreferredConfig = mBitmapConfig;
tmpOptions.inSampleSize = sampleSize;
tmpOptions.inJustDecodeBounds = false;

            return mDecoder.decodeRegion(rect, tmpOptions);
        }
    }

    return null;
}

超长图无法显示

你好,我在微博上下的一张尺寸为(17907*440)的图片无法显示,怎么解决呢?

引用方式

如果能添加到center 就完美了.1.Gradle添加依赖 (推荐)

有个概率性Bug

这里有个概率性Bug,错误日志如下:
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.os.HandlerThread.quit()' on a null object reference
at cn.kejin.ximageview.BitmapManager.onDestroy(BitmapManager.java:210)
at cn.kejin.ximageview.XImageView.onDetachedFromWindow(XImageView.java:211)
at android.view.View.dispatchDetachedFromWindow(View.java:15846)
at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3372)
at android.view.ViewGroup.removeViewInternal(ViewGroup.java:4950)
at android.view.ViewGroup.removeViewInternal(ViewGroup.java:4923)
at android.view.ViewGroup.removeView(ViewGroup.java:4854)
at android.support.v4.view.ViewPager.removeView(ViewPager.java:1359)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1178)
at android.support.v4.app.FragmentManagerImpl.detachFragment(FragmentManagerImpl.java:1415)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:723)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1624)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManagerImpl.java:570)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1106)
at android.support.v4.view.ViewPager.populate(ViewPager.java:952)
at android.support.v4.view.ViewPager$3.run(ViewPager.java:251)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:920)
at android.view.Choreographer.doCallbacks(Choreographer.java:695)
at android.view.Choreographer.doFrame(Choreographer.java:628)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:906)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7224)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.