Android library (AAR). Highly configurable, easily extendable deep zoom view for displaying huge images without loss of detail. Perfect for photo galleries, maps, building plans etc.

Overview

Subsampling Scale Image View

A custom image view for Android, designed for photo galleries and displaying huge images (e.g. maps and building plans) without OutOfMemoryErrors. Includes pinch to zoom, panning, rotation and animation support, and allows easy extension so you can add your own overlays and touch event detection.

The view optionally uses subsampling and tiles to support very large images - a low resolution base layer is loaded and as you zoom in, it is overlaid with smaller high resolution tiles for the visible area. This avoids holding too much data in memory. It's ideal for displaying large images while allowing you to zoom in to the high resolution details. You can disable tiling for smaller images and when displaying a bitmap object. There are some advantages and disadvantages to disabling tiling so to decide which is best, see the wiki.

Guides

Migration guides

Versions 3.9.0, 3.8.0 and 3.0.0 contain breaking changes. Migration instructions can be found in the wiki.

Download the sample app

Get it on Google Play

Kotlin Sample App on GitHub

Demo

Demo

Features

Image display

  • Display images from assets, resources, the file system or bitmaps
  • Automatically rotate images from the file system (e.g. the camera or gallery) according to EXIF
  • Manually rotate images in 90° increments
  • Display a region of the source image
  • Use a preview image while large images load
  • Swap images at runtime
  • Use a custom bitmap decoder

With tiling enabled:

  • Display huge images, larger than can be loaded into memory
  • Show high resolution detail on zooming in
  • Tested up to 20,000x20,000px, though larger images are slower

Gesture detection

  • One finger pan
  • Two finger pinch to zoom
  • Quick scale (one finger zoom)
  • Pan while zooming
  • Seamless switch between pan and zoom
  • Fling momentum after panning
  • Double tap to zoom in and out
  • Options to disable pan and/or zoom gestures

Animation

  • Public methods for animating the scale and center
  • Customisable duration and easing
  • Optional uninterruptible animations

Overridable event detection

  • Supports OnClickListener and OnLongClickListener
  • Supports interception of events using GestureDetector and OnTouchListener
  • Extend to add your own gestures

Easy integration

  • Use within a ViewPager to create a photo gallery
  • Easily restore scale, center and orientation after screen rotation
  • Can be extended to add overlay graphics that move and scale with the image
  • Handles view resizing and wrap_content layout

Quick start

1) Add this library as a dependency in your app's build.gradle file.

dependencies {
    implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0'
}

If your project uses AndroidX, change the artifact name as follows:

dependencies {
    implementation 'com.davemorrissey.labs:subsampling-scale-image-view-androidx:3.10.0'
}

2) Add the view to your layout XML.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

3a) Now, in your fragment or activity, set the image resource, asset name or file path.

SubsamplingScaleImageView imageView = (SubsamplingScaleImageView)findViewById(id.imageView);
imageView.setImage(ImageSource.resource(R.drawable.monkey));
// ... or ...
imageView.setImage(ImageSource.asset("map.png"))
// ... or ...
imageView.setImage(ImageSource.uri("/sdcard/DCIM/DSCM00123.JPG"));

3b) Or, if you have a Bitmap object in memory, load it into the view. This is unsuitable for large images because it bypasses subsampling - you may get an OutOfMemoryError.

SubsamplingScaleImageView imageView = (SubsamplingScaleImageView)findViewById(id.imageView);
imageView.setImage(ImageSource.bitmap(bitmap));

Photo credits

About

Copyright 2018 David Morrissey, and licensed under the Apache License, Version 2.0. No attribution is necessary but it's very much appreciated. Star this project if you like it!

Comments
  • Multithreading Issue

    Multithreading Issue

    Hi Dave - I seem to have come across an odd issue dealing with multithreading that results in Image View hanging.

    Whenever there are multiple threads active in the app performing other tasks (eg running multiple network threads) it seems the Image View will hang and not load an image until previous threads complete or free up.

    What I believe may be happening (pl. feel free to correct) is that the Image View internally uses AsyncTask - which has limited number of concurrent threads per app domain that can run depending on SDK version. I believe its around 5 threads, subsequent threads will be queued.

    This could be a bit problematic for apps with lots of processing. What makes it worse is that the problem will not be evident on some SDKs/devices. There's also very little gained by going with AsyncTask VS. using Threads directly, other than syntactic convenience I suppose :)

    Would it be possible to replace AsyncTask in the next library update ?

    Thanks!

    opened by ghost 42
  • Image Zoom Blurry in Some Parts of the Image

    Image Zoom Blurry in Some Parts of the Image

    Hello - reaching out with an odd issue that I have a hard time reproducing. A number of my users are reporting that when they zoom in on some parts of the image, it just stays blurry and never clears up.

    What I mean by that is, whenever you zoom in on an image, its a bit blurry at first but then clears up as the processing takes place. With these reports users are saying that in certain areas of the image always stay blurry on zoom no matter how long they wait. But other parts of the image are ok.

    From what I see this is on Samsung devices, a number of reports are from Galaxy S5.

    This is a bit odd as I never saw anything like this in my own testing with 15 devices. Have you experienced anything similar, and if so how to best tackle this issue?

    Thanks!

    opened by ghost 23
  • Out of Memory when rotating

    Out of Memory when rotating

    Hi, some users reports Out of Memory when they use rotate of viewed image. On my device (Samsung Galaxy Note II) is this problem too. I tested it on version 2.3.0 also but this problem is there still. Rotate button has this simple functionality:

    int actualOrientation = mPicture.getOrientation();
    mPicture.setOrientation(actualOrientation == 270 ? 0 : actualOrientation + 90);
    

    I add logs to SubsamplingScaleImageView.BitmapTileTask.doInBackground() to synchronized block before decodeRegion and before createBitmap with tag SUBSAMPLING ROTATE (this is in exception log below). The proble is that bitmap gets big dimensions from decodeRegion - dimensions are original of image source with sampleSize = 1. Is there another procedure for change orientation for eliminate Out of Memory?

    D/SUBSAMPLING ROTATE﹕ tile: Rect(0, 0 - 2448, 3264); sampleSize: 1
    D/dalvikvm﹕ GC_FOR_ALLOC freed 5088K, 41% free 27412K/45956K, paused 25ms, total 26ms
    I/dalvikvm-heap﹕ Grow heap (frag case) to 43.484MB for 15980560-byte allocation
    D/dalvikvm﹕ GC_FOR_ALLOC freed 329K, 31% free 42689K/61564K, paused 17ms, total 17ms
    D/SUBSAMPLING ROTATE﹕ bitmap dim: 3264 x 2448
    D/dalvikvm﹕ GC_FOR_ALLOC freed 1K, 31% free 42689K/61564K, paused 15ms, total 15ms
    I/dalvikvm-heap﹕ Forcing collection of SoftReferences for 15980560-byte allocation
    D/dalvikvm﹕ GC_BEFORE_OOM freed 70K, 31% free 42618K/61564K, paused 27ms, total 27ms
    E/dalvikvm-heap﹕ Out of memory on a 15980560-byte allocation.
    I/dalvikvm﹕ "AsyncTask #2" prio=5 tid=12 RUNNABLE
    I/dalvikvm﹕ | group="main" sCount=0 dsCount=0 obj=0x4368dde0 self=0x5b526ce0
    I/dalvikvm﹕ | sysTid=31125 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1532129584
    I/dalvikvm﹕ | state=R schedstat=( 562850949 168737745 1402 ) utm=46 stm=10 core=3
    I/dalvikvm﹕ at android.graphics.Bitmap.nativeCreate(Native Method)
    I/dalvikvm﹕ at android.graphics.Bitmap.createBitmap(Bitmap.java:726)
    I/dalvikvm﹕ at android.graphics.Bitmap.createBitmap(Bitmap.java:703)
    I/dalvikvm﹕ at android.graphics.Bitmap.createBitmap(Bitmap.java:636)
    I/dalvikvm﹕ at com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView$BitmapTileTask.doInBackground(SubsamplingScaleImageView.java:1197)
    I/dalvikvm﹕ at com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView$BitmapTileTask.doInBackground(SubsamplingScaleImageView.java:1167)
    I/dalvikvm﹕ at android.os.AsyncTask$2.call(AsyncTask.java:287)
    I/dalvikvm﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:234)
    I/dalvikvm﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
    I/dalvikvm﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
    I/dalvikvm﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
    I/dalvikvm﹕ at java.lang.Thread.run(Thread.java:841)
    I/dalvikvm﹕ [ 03-09 10:24:31.503 31026:31125 W/dalvikvm ]
        threadid=12: thread exiting with uncaught exception (group=0x4195b700)
    E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #2
        java.lang.RuntimeException: An error occured while executing doInBackground()
                at android.os.AsyncTask$3.done(AsyncTask.java:299)
                at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
                at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
                at java.util.concurrent.FutureTask.run(FutureTask.java:239)
                at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
                at java.lang.Thread.run(Thread.java:841)
         Caused by: java.lang.OutOfMemoryError
                at android.graphics.Bitmap.nativeCreate(Native Method)
                at android.graphics.Bitmap.createBitmap(Bitmap.java:726)
                at android.graphics.Bitmap.createBitmap(Bitmap.java:703)
                at android.graphics.Bitmap.createBitmap(Bitmap.java:636)
                at com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView$BitmapTileTask.doInBackground(SubsamplingScaleImageView.java:1197)
                at com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView$BitmapTileTask.doInBackground(SubsamplingScaleImageView.java:1167)
                at android.os.AsyncTask$2.call(AsyncTask.java:287)
                at java.util.concurrent.FutureTask.run(FutureTask.java:234)
                at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
                at java.lang.Thread.run(Thread.java:841)
    D/xxxFragment﹕ onPause
    I/com.sjl.util.Foreground﹕ still foreground
    V/GAV4﹕ Thread[GAThread,5,main]: Loaded clientId
    D/xxxFragment﹕ onDetach
    E/ViewRootImpl﹕ sendUserActionEvent() mView == null
    

    Thanks...

    P.S.: let me know if you need my image file for testing please

    EDIT 1: for this is not relevant if image is zoom out or in in view component.

    EDIT 2: btw this exception is catched for Exception in BitmapTileTask.doInBackground(), but OutOfMemory is not its child and because it is in async task it is not possible catch in my application. Please add catching OOM.

    EDIT 3: hm, catching OOM is not recommended, e.g. http://stackoverflow.com/questions/1692230/is-it-possible-to-catch-out-of-memory-exception-in-java

    bug 
    opened by PetrDana 21
  • 3.7.0: IllegalArgumentException: pointerIndex out of range

    3.7.0: IllegalArgumentException: pointerIndex out of range

    I upgraded to the new version 3.7.0 and found a new issue. When I zoom while an image is still loading I get the following exception:

    java.lang.IllegalArgumentException: pointerIndex out of range at android.view.MotionEvent.nativeGetAxisValue(Native Method) at android.view.MotionEvent.getX(MotionEvent.java:2111) at android.support.v4.view.ViewPager.onInterceptTouchEvent(ViewPager.java:2064) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2313) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2712) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2428) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2712) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2428) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2712) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2428) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2712) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2428) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2712) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2428) at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2679) at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1797) at android.app.Activity.dispatchTouchEvent(Activity.java:2878) at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68) at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2640) at android.view.View.dispatchPointerEvent(View.java:9234) at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4785) at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4623) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4174) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4227) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4193) at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4303) at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4201) at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4360) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4174) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4227) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4193) at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4201) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4174) at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6652) at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6536) at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6507) at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6742) at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185) at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method) at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176) at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6713) at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:6765) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777) at android.view.Choreographer.doCallbacks(Choreographer.java:590) at android.view.Choreographer.doFrame(Choreographer.java:558) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:145) at android.app.ActivityThread.main(ActivityThread.java:6117) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(Zygot 02-02 06:56:29.360 2975-3425/? W/ActivityManager: Force finishing activity

    opened by RocketRider 18
  • Image padding

    Image padding

    Hey, just discovered the lib and great job.

    I'm currently using PhotoView which allows padding on images. As far as I can tell padding is ignored when determining the initial image size when using subsampling-scale-image-view.

    If it helps this was the previous issue raised for PhotoView:

    https://github.com/chrisbanes/PhotoView/issues/29

    Cheers

    enhancement question 
    opened by laurencedawson 18
  • quick initial render for very large images?

    quick initial render for very large images?

    I would like to use this library for some very large jpeg images (20480x20480, about 20mb). Putting one of the images into your sample, I see that the initial load takes 5 seconds on my Nexus 7. That's pretty decent for such a large image (my laptop takes two or three seconds, too), but I wonder if there would be a way to extend your library to allow for a pre-scaled smaller image to be displayed while the library is working away on a large one, for the sake of instant user gratification. After the initial render, your library's scrolling is really smooth, and it could make for a great improvement in my app (LunarMap, which currently uses a kludgy method with lots of pre-rendered tiles at different zoom levels).

    I could extend your library in this way, but you will know a lot better how to most neatly implement it, and how it would most neatly fit with your ideas how the API works. Advice would be appreciated.

    enhancement 
    opened by arpruss 15
  • Device specific lag in ViewPager

    Device specific lag in ViewPager

    Hi,

    I'm experiencing very weird lag on my Moto X Pure. I've SubsamplingScaleImageView (match parent,x,y) in a ViewPager without any fancy stuff, very much sticking to the sample, and somehow a lot of bigger Pictures (devices has 21mpx camera) are causing huge Lag (~50 frame jumps) on my Motorola X Pure.

    The lag is, when swiping away from the already loaded picture. First I thought, it was because of the size of the image. But other Images from the same camera/app are working well, even with bigger file sizes. I debugged a lot and tried a lot of stuff (i.e. setParallelLoadingEnabled, OffscreenPageLimit, ...) until I almost gave up and tried other devices. On the Oneplus One, and even on the MotoG 2014 the exact same pictures with the exact same AppBuild are not lagging and buttery smooth, which is pretty weird, as both devices have much weaker hardware. Therefore I assume there might be something in the operating system of my X, though I certainly have no clue where to point my finger at. The Oneplus runs Android 5, while the Moto G is on Android 6, like my X. So major Android version doesn't seem to be the factor as well. I attached two images from my Moto X camera. One with about 9 MB not causing lag, and the other with about 7 MB causing lag for the option to maybe reproduce the issue.

    As it seems device/system related I thought it worth posting. It could hint towards iusses with specific library versions or similar...(?) Is there any method, which could lead to clues on the issues or is this maybe somthing known/expected?

    Best regards Simon

    Edit: Sorry, filenames get changed with upload. The one with the car mirror is the bigger pic, that doesn't cause lag.

    lag no_lag

    opened by zmnpl 14
  • Loaded bitmap is

    Loaded bitmap is "pixelated"

    Some images are loading in very poor quality. It's always the same images, but I can't figure out what they have in common. Here is the example of image and a screenshot how it looks like on a device. (btw, I use subsampling view). The issue persists on every device I tried and also on genymotion emulator, so I think it's a bug sun-ken-rock-v01-c03---20 image

    bug 
    opened by SammyVimes 14
  • Potential ProGuard and/or attribute issues with 3.7.0

    Potential ProGuard and/or attribute issues with 3.7.0

    Several users have reported issues with version 3.7.0, e.g. #350 #351 #353 #354 Initial evaluation suggests the changes are related to updated build dependencies, merged in #306

    Let's keep this issue to discuss further findings to get to the bottom of this.

    opened by friederbluemle 13
  • Large, irregular size images

    Large, irregular size images

    Hi,

    Did you tested SubsamplingScaleImageView on irregular size images, for example 480x4000? I know it should worked, but is it optimized? I'm looking for an idea to display it, cause making listview with N splited images is not a best workaround, especially when you want to zoom and pan.

    question 
    opened by Chesteer89 13
  • Problems - exif oriented image

    Problems - exif oriented image

    Sometimes they are not placed correctly, instead of centered they are wrongly placed on top, probably becasue they are not rotated as they should be. I use the images in a ViewPager and the auto rotation does sometimes work, sometimes not...

    My solution looks like following and is working always, don't know why yours does not (I only use images from the sd card, so they are either from the media store directly or they have an uri created from a path - this is for all hidden images):

    if (Temp.ROTATE_BIG_IMAGE_MANUALLY)
        ivImage.setOrientation(((Image) mMediaFile).getRotation());
    else
        ivImage.setOrientation(SubsamplingScaleImageView.ORIENTATION_USE_EXIF);
    ivImage.setMinScale(0.1f);
    ivImage.setMaxScale(4f);
    ivImage.setOnClickListener(this);
    ivImage.setImage(ImageSource.uri(mMediaFile.getUri()));
    ivImage.setOnImageEventListener(this);
    

    With following getRotation function:

    public int getRotation()
    {
        int exifOrientationInDegress = 0;
        if (isFromMediaStore())
        {
            final String[] columns = { MediaStore.Images.Media.ORIENTATION };
            final Cursor cursor = MainApp.get().getContentResolver().query(getUri(), columns, null, null, null);
            if (cursor != null)
            {
                if (cursor.moveToFirst())
                {
                    exifOrientationInDegress = cursor.getInt(0);
                }
                cursor.close();
            }
        }
        else
        {
            ExifInterface exifReader = null;
            try
            {
                exifReader = new ExifInterface(getRealPath());
                exifOrientationInDegress = MediaUtil.convertExifOrientationToDegrees(exifReader.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0));
            }
            catch (IOException e)
            {
                L.e(this, e);
            }
        }
        return exifOrientationInDegress;
    }
    

    If I manually rotate the image, everything is working fine

    opened by MFlisar 12
  • NullPointException Attempt to read from field

    NullPointException Attempt to read from field "Anim.listener" on a null object reference

    Please provide as much of the following information as possible. Please do not raise issues to ask for help developing your app.

    Expected behaviour

    won't crash

    Actual behaviour

    sometimes crash

    Steps to reproduce

    zoom and move image frequently, there is a chance that crash. may be add and remove animation continuously cause to error.

    Fatal Exception: java.lang.NullPointerException
    Attempt to read from field 'com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView$OnAnimationEventListener com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView$Anim.listener' on a null object reference
    com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView$Anim.access$2800 (SubsamplingScaleImageView.java:1898)
    com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.onDraw (SubsamplingScaleImageView.java:1018)
    android.view.View.draw (View.java:23017)
    android.view.View.updateDisplayListIfDirty (View.java:21885)
    android.view.ViewGroup.recreateChildDisplayList (ViewGroup.java:4526)
    android.view.ViewGroup.dispatchGetDisplayList (ViewGroup.java:4499)
    android.view.View.updateDisplayListIfDirty (View.java:21838)
    android.view.ViewGroup.recreateChildDisplayList (ViewGroup.java:4526)
    android.view.ViewGroup.dispatchGetDisplayList (ViewGroup.java:4499)
    android.view.View.updateDisplayListIfDirty (View.java:21838)
    android.view.ViewGroup.recreateChildDisplayList (ViewGroup.java:4526)
    android.view.ViewGroup.dispatchGetDisplayList (ViewGroup.java:4499)
    android.view.View.updateDisplayListIfDirty (View.java:21838)
    android.view.ViewGroup.recreateChildDisplayList (ViewGroup.java:4526)
    android.view.ViewGroup.dispatchGetDisplayList (ViewGroup.java:4499)
    android.view.View.updateDisplayListIfDirty (View.java:21838)
    

    (Include your setup code, and where relevant, your layout XML)

    Affected devices

    Many Android devices (Specific devices, screen densities, SDK versions)

    Affected images

    (Attach images you have problems with)

    opened by PeacefulGemini 0
  • the image rotate auto

    the image rotate auto

    when the image width and height both bigger than displayMetrics,the loaded image will be rotate 90 , I'll be pleasure if someone could answer this question

    opened by andrewsSong 0
  • Open picture blinks

    Open picture blinks

    Please provide as much of the following information as possible. Please do not raise issues to ask for help developing your app.

    Expected behaviour

    Seamless switching from preview image to real image

    Actual behaviour

    The picture with angle change will be black for a while when switching

    Steps to reproduce

    val source = ImageSource.uri(Uri.fromFile(file)).dimensions(wh[0],wh[1]) scaleView.setImage(source,ImageSource.bitmap(bitmap))

    Problem code: subsamplingscaleimageview.ontilesinitiated

    Affected devices

    all

    Affected images

    (Attach images you have problems with)

    https://user-images.githubusercontent.com/20008456/183365276-e331c1b7-81b5-43e4-a337-c43e9865a967.mp4

    opened by MouseKing1993 1
  • onSingleTapConfirmed gesture only being called when debugger is attached

    onSingleTapConfirmed gesture only being called when debugger is attached

    Expected behaviour

    onSingleTapConfirmed should get a callback and show a Log/Toast when on called according to the logic but it doesn't.

    Actual behaviour

    It doesn't get the callback but it does get the callback if the debugger is attached to the device.

    Steps to reproduce

    Tested on Emulator with the following code - `

    gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                if (mapIv.isReady()) {
                    PointF sCoord = mapIv.viewToSourceCoord(e.getX(), e.getY());
                    Toast.makeText(HomeActivity.this, "touched x:" + sCoord.x + ", y:" + sCoord.y, Toast.LENGTH_LONG).show();
                }
                return true;
            }
        });
        mapIv.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                return gestureDetector.onTouchEvent(motionEvent);
            }
        });
    

    `

    Affected devices

    Tested on Pixel 3a emulator with android 10

    opened by akashpopat-honest 1
Releases(v3.10.0)
  • v3.10.0(Mar 15, 2018)

  • v3.9.0(Dec 2, 2017)

    This release contains breaking changes. If you use a custom ImageRegionDecoder, changes may be required to make it thread safe. For full details see the migration guide.

    These changes are discussed on #120.

    • Replaced setParallelLoadingEnabled with an option to supply a custom executor - setExecutor(Executor).
    • Made AsyncTask.THREAD_POOL_EXECUTOR the default, to reduce contention with other background tasks.
    • Removed synchronization of ImageRegionDecoder.decodeRegion calls to allow for parallel decoding by decoders that support it.
    • Tiles are now loaded during gestures and animations instead of waiting until they end. This can be disabled with setEagerLoadingEnabled(false)
    • Added experimental class SkiaPooledImageRegionDecoder which maintains a small pool of BitmapRegionDecoder instances to allow for parallel decoding when combined with a multi-threaded executor.
    Source code(tar.gz)
    Source code(zip)
    subsampling-scale-image-view-3.9.0.aar(63.93 KB)
  • v3.8.0(Nov 16, 2017)

    • Breaking change Minimum supported SDK has changed from 10 to 14. This was required to add the new EXIF support library.
    • Default behaviour change Image quality is now capped at 320dpi (approximately retina quality) instead of matching the screen's density, which results in high memory use and poor performance when displaying large images on very high density screens. The difference in quality is usually unnoticeable, especially with photos. Use setMinimumTileDpi(int) to override the default.
    • #273 #295 Added minimum scale type SCALE_TYPE_START. This displays the image filling the view width and height, and scrolled to the top left.
    • #284 Double tap is now always interpreted as zoom when zoomed out, to avoid problems when minimum and maximum scale are very close.
    • #298 Added getPanRemaining(RectF), which exposes the pan remaining in each direction, in screen pixels.
    • #329 Allow OnClickListener to work before the image has loaded.
    • #331 Added methods to convert view coordinates to source file coordinates to enable the visible area to be extracted from the source image. visibleFileRect(Rect) and viewToFileRect(Rect, Rect).
    • #344 Guard against null vFocusStart in animation.
    • Improved debug overlay.
    Source code(tar.gz)
    Source code(zip)
    subsampling-scale-image-view-3.8.0.aar(54.13 KB)
  • v3.7.2(Nov 1, 2017)

  • v3.7.1(Oct 25, 2017)

  • v3.7.0(Oct 20, 2017)

    • Forced removal of implicit permissions READ_PHONE_STATE, READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE
    • #279 Include proguard rules to stop removal of default constructors
    • #302 Pass vertical move touch events to parent if not consumed
    • #314 Added null-check per method in onStateChangedListener
    • #349 Support for other bitmap formats (not just default RGB565)
    Source code(tar.gz)
    Source code(zip)
    subsampling-scale-image-view-3.7.0.aar(53.16 KB)
  • v3.6.0(Nov 5, 2016)

    • #127 If max tile dimensions have been set and dimensions are known, load base layer without waiting for onDraw. This improves ViewPager support - the next image can be eagerly loaded.
    • #148 Revised behaviour of zoom gestures as the image fills the screen for a smoother animation.
    • #171 Added a new image state listener class to allow activites to receive pan and zoom change events.
    • #206 Allow maximum tile dimensions to be set, so performance and memory usage can be optimised when the device supports excessively large tiles.
    • #211 Made double tap tolerance density aware for improved high density screen support.
    • #216 Ensure cursors are closed after exceptions.
    • #222 Added image event for preview released so it can be recycled.
    • #245 Avoid NPE if view has been detached from parent.
    • #253 Corrected position of tile background colour for preview image.
    • #262 Method to check whether an image has been set.
    Source code(tar.gz)
    Source code(zip)
    subsampling-scale-image-view-3.6.0.aar(52.35 KB)
  • v3.5.0(Apr 3, 2016)

  • v3.4.1(Oct 13, 2015)

  • v3.4.0(Oct 3, 2015)

    BitmapRegionDecoder has known issues decoding some images, particularly JPEGs, which can result in images being decoded highly pixellated, grayscale, or completely garbled. BitmapFactory is unaffected by any of these bugs so is much more reliable.

    This library will now use BitmapRegionDecoder to decode the bounds of the image, and if it is smaller than the canvas maximum bitmap size, and the whole image is required at native resolution, BitmapFactory is automatically used instead. This should make the display of small to medium size images from unknown sources much more reliable. As screen densities continue to increase, BitmapFactory will be used more frequently.

    Users on devices with low resolution screens viewing large images are more likely to see the problems caused by BitmapRegionDecoder.

    Source code(tar.gz)
    Source code(zip)
    subsampling-scale-image-view-3.4.0.aar(47.08 KB)
  • v3.3.0(Sep 30, 2015)

  • v3.2.0(Aug 30, 2015)

  • v3.1.4(Jun 14, 2015)

  • v3.1.3(Mar 24, 2015)

  • v3.1.2(Mar 15, 2015)

    • Using a matrix to rotate tiles causes rounding errors resulting in intermittent black lines between them, so this change has been reverted.
    • Tile size is temporarily capped at 2048x2048 to reduce the likelihood of OOMEs while creating rotated copies.

    Remember to check your PNGs do not have an alpha layer to reduce the chance of an OOME, especially when using rotation!

    Source code(tar.gz)
    Source code(zip)
    subsampling-scale-image-view-3.1.2.aar(44.80 KB)
  • v3.1.1(Mar 15, 2015)

  • v3.1.0(Mar 10, 2015)

  • v3.0.0(Mar 8, 2015)

    This release includes breaking changes. Migrating activities and subclasses to the new version is simple, please see the notes in the README.

    • Combined ScaleImageView and SubsamplingScaleImageView into one class. Tiling can be enabled or disabled as appropriate. SubsamplingScaleImageView can now display a bitmap.
    • Refactored ready events. When onReady is called, the view is ready to display an image (in previous versions this only indicated the source dimensions were known).
    • Simplified method of specifying the source image, reducing the proliferation of setImage... methods.
    • #37 Allow use of a preview image from resources, assets, filesystem or bitmap to enable gestures while a large full size image is loading.
    • #46 Display a specified region of the source file.
    • #40 Listener interface can be used to receive load errors and ready events.
    • #41 No objects allocated in onDraw or onTouchEvent to improve efficiency.
    • Fixed a bug with tile sizes that resulted in the last few pixels of some images being cropped.
    • Fixed a bug with double tap zoom not respecting disabled pan.
    • Fixed incorrect requested centre point after size change.
    Source code(tar.gz)
    Source code(zip)
    subsampling-scale-image-view-3.0.0.aar(44.83 KB)
  • v2.4.0(Feb 23, 2015)

  • v2.3.0(Jan 12, 2015)

Owner
null
Big image viewer supporting pan and zoom, with very little memory usage and full featured image loading choices. Powered by Subsampling Scale Image View, Fresco, Glide, and Picasso. Even with gif and webp support! 🍻

BigImageViewer Big image viewer supporting pan and zoom, with very little memory usage and full featured image loading choices. Powered by Subsampling

Piasy 3.9k Dec 30, 2022
Android View widget for displaying GIF animations.

gif-movie-view Android View widget for displaying GIF animations. To show animated GIF in your application just add GifMovieView into your layout.

Sergey Bakhtiarov 459 Nov 10, 2022
Customizable Android full screen image viewer for Fresco library supporting "pinch to zoom" and "swipe to dismiss" gestures. Made by Stfalcon

This project is no longer supported. If you're able to switch from Fresco to any other library that works with the Android's ImageView, please migrate

Stfalcon LLC 1.8k Dec 19, 2022
Android ImageView widget with zoom and pan capabilities

ImageViewTouch for Android ImageViewTouch is an android ImageView widget with zoom and pan capabilities. This is an implementation of the ImageView wi

Alessandro Crugnola 1.9k Jan 4, 2023
Implements pinch-zoom, rotate, pan as an ImageView for Android 2.1+

GestureImageView This is a simple Android View class which provides basic pinch and zoom capability for images. Can be used as a replacement for a sta

Jason 1.1k Nov 10, 2022
Slider-Gallery-Zoom: image slider for android supporting indicator and auto scroll with clicking on image

image slider supporting indicator and auto scroll with clicking on image to open full screen image slider swipe and pinch zoom gestures like gallery,just pass your images and the position of the current image.

Mahmoud Elian 3 May 28, 2022
Tutorial Double Tap Pinch to Zoom with kotlin

Double-Tap-Pinch-Zoom Tutorial Double Tap Pinch to Zoom Tutorial Build with Andr

Azhar Rivaldi 6 Apr 13, 2022
PinchToZoom - Pinch to zoom used within list like Instagram

Pinch To Zoom ?? Description Pinch to Zoom with Pan Gestures like Instagram ?? Motivation and Context Big Thanks ???? to the guy and his amazing repo

Vivek Sharma 12 Apr 12, 2022
An awesome photo album viewer.

An awesome photo album viewer.

null 15 Jun 13, 2022
Mobile development Exercise Simple photo viewer

Mobile development Simple Photo viewer Exercise A simple photo viewer based on Udacitys example app "dice roller"." Mobile development Exercise Simple

null 0 Oct 16, 2021
Custom view for circular images in Android while maintaining the best draw performance

CircularImageView Custom view for circular images in Android while maintaining the best draw performance Usage To make a circular ImageView, add this

Pkmmte Xeleon 1.2k Dec 28, 2022
Android library project for cropping images

I guess people are just cropping out all the sadness An Android library project that provides a simple image cropping Activity, based on code from AOS

Jamie McDonald 4.5k Dec 29, 2022
An open source Android library that allows the visualization of large images with gesture capabilities

ByakuGallery ByakuGallery is an open source Android library that allows the visualization of large images with gesture capabilities. This lib is based

Diego Lima 311 Dec 4, 2022
Android ImageView that handles animated GIF images

GifImageView Android ImageView that handles Animated GIF images Usage In your build.gradle file: dependencies { compile 'com.felipecsl:gifimageview:

Felipe Lima 1.1k Mar 9, 2021
A gallery used to host an array of images

ImageGallery Overview A gallery used to host an array of images You can add one or more images to the gallery Support for using Palette to set the bac

Etienne Lawlor 645 Dec 18, 2022
DMIV aims to provide a flexible and customizable instrument for automated images moving on display. It provides scroll, gyroscope or time based moving. But you can create your own evaluator.

DexMovingImageView DMIV aims to provide a flexible and customizable instrument for automated images moving on display. It provides scroll, gyroscope o

Diego Grancini 310 Feb 7, 2022
RasmView - an Android drawing view; it provides a view that allows users to draw on top of a bitmap.

RasmView RasmView is an Android drawing library; it provides a view that allows users to draw on top of a bitmap. Demo https://www.youtube.com/watch?v

Raed Mughaus 39 Dec 23, 2022
Apply custom effects on view backgrounds

View Filters At the beginning the only purpose was to blur all layers below. Now you can do more : Blur background views easily Create custom filters

Mad Mirrajabi 180 Nov 25, 2022