Convert Figma logo to code with AI

stfalcon-studio logoFrescoImageViewer

Customizable Android full screen image viewer for Fresco library supporting "pinch to zoom" and "swipe to dismiss" gestures. Made by Stfalcon

1,808
285
1,808
39

Top Related Projects

ImageView and FrameLayout with gestures control and position animation

图片浏览缩放控件

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.

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! 🍻

Quick Overview

FrescoImageViewer is an Android library that provides a customizable full-screen image viewer based on the Fresco library. It allows for smooth image loading, zooming, and panning, with support for various image formats and sources.

Pros

  • Seamless integration with Fresco library for efficient image loading and caching
  • Customizable UI elements, including overlay views and transitions
  • Support for zooming and panning gestures
  • Ability to handle large images and various formats (including GIFs and WebP)

Cons

  • Requires Fresco library as a dependency, which may increase app size
  • Limited documentation and examples for advanced customization
  • Not actively maintained (last update was in 2018)
  • May require additional setup for certain image formats or sources

Code Examples

  1. Basic usage to show a single image:
val imageUrls = listOf("https://example.com/image.jpg")
ImageViewer.Builder(context, imageUrls)
    .show()
  1. Customizing the overlay view:
ImageViewer.Builder(context, imageUrls)
    .setOverlayView(customOverlayView)
    .setImageChangeListener { position ->
        customOverlayView.setDescription(descriptions[position])
    }
    .show()
  1. Implementing a custom transition:
ImageViewer.Builder(context, imageUrls)
    .setStartPosition(startPosition)
    .setImageChangeListener { position ->
        viewPager.setCurrentItem(position, true)
    }
    .setOnDismissListener {
        supportFinishAfterTransition()
    }
    .show()

Getting Started

  1. Add the JitPack repository to your project's build.gradle:
allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
  1. Add the dependency to your app's build.gradle:
dependencies {
    implementation 'com.github.stfalcon:frescoimageviewer:0.5.0'
}
  1. Initialize Fresco in your Application class:
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Fresco.initialize(this)
    }
}
  1. Use the ImageViewer in your activity or fragment:
val imageUrls = listOf("https://example.com/image1.jpg", "https://example.com/image2.jpg")
ImageViewer.Builder(context, imageUrls)
    .setStartPosition(0)
    .show()

Competitor Comparisons

ImageView and FrameLayout with gestures control and position animation

Pros of GestureViews

  • Supports a wider range of gesture interactions, including rotation and double-tap-to-zoom
  • Provides smoother animations and transitions between image states
  • Offers more customization options for gesture behaviors and UI elements

Cons of GestureViews

  • Lacks built-in support for image loading libraries like Fresco
  • May require more setup and configuration compared to FrescoImageViewer
  • Does not include a ready-to-use fullscreen image viewer out of the box

Code Comparison

GestureViews:

GestureImageView imageView = findViewById(R.id.image);
imageView.getController().enableScrollInViewPager();
imageView.getController().setDoubleTapZoom(3f);

FrescoImageViewer:

new ImageViewer.Builder<>(this, images)
    .setStartPosition(startPosition)
    .show();

GestureViews provides more granular control over gesture behaviors, while FrescoImageViewer offers a simpler API for quick implementation of a fullscreen image viewer. GestureViews requires more code to set up individual views, but allows for greater customization. FrescoImageViewer's builder pattern makes it easier to create a viewer with fewer lines of code, but with less flexibility in terms of gesture controls.

图片浏览缩放控件

Pros of PhotoView

  • Simpler implementation, easier to integrate into existing projects
  • Supports a wider range of image sources, including drawables and file paths
  • Offers more customization options for gestures and animations

Cons of PhotoView

  • Lacks built-in image loading and caching capabilities
  • May require additional libraries for advanced image processing
  • Less optimized for memory usage compared to FrescoImageViewer

Code Comparison

FrescoImageViewer:

ImageViewer.Builder(this, images)
    .setStartPosition(startPosition)
    .show()

PhotoView:

PhotoView photoView = findViewById(R.id.photo_view);
photoView.setImageResource(R.drawable.image);

FrescoImageViewer uses a builder pattern to configure and display images, while PhotoView is implemented as a custom view that can be directly added to layouts. FrescoImageViewer provides a more streamlined approach for displaying multiple images in a gallery-like format, whereas PhotoView offers more flexibility for single image display and manipulation within existing layouts.

Both libraries have their strengths, with FrescoImageViewer excelling in memory management and image loading, while PhotoView offers more customization options and easier integration for single image scenarios.

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.

Pros of subsampling-scale-image-view

  • Supports very large images (over 100MP) through efficient subsampling and tiling
  • Offers smooth pan and zoom functionality with configurable max/min scale
  • Provides easy integration with custom touch event handling

Cons of subsampling-scale-image-view

  • Limited to displaying single images, unlike FrescoImageViewer's gallery support
  • Lacks built-in image loading and caching capabilities provided by Fresco library
  • Does not offer customizable overlay views or advanced UI customization options

Code Comparison

subsampling-scale-image-view:

SubsamplingScaleImageView imageView = new SubsamplingScaleImageView(context);
imageView.setImage(ImageSource.resource(R.drawable.large_image));
imageView.setMaxScale(10f);

FrescoImageViewer:

new ImageViewer.Builder<>(this, images)
    .setStartPosition(startPosition)
    .setImageChangeListener(getImageChangeListener())
    .show();

Summary

subsampling-scale-image-view excels in handling large images with efficient memory usage and smooth zooming, making it ideal for applications requiring detailed image inspection. FrescoImageViewer, on the other hand, offers a more comprehensive solution for image galleries with built-in loading and caching through the Fresco library. The choice between the two depends on specific project requirements, such as image size, gallery functionality, and integration with existing image loading libraries.

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! 🍻

Pros of BigImageViewer

  • Supports multiple image loading engines (Fresco, Glide, and custom implementations)
  • Offers more advanced features like progressive JPEG loading and custom progress indicators
  • Provides better memory management for large images

Cons of BigImageViewer

  • May have a steeper learning curve due to more configuration options
  • Less focused on a specific use case compared to FrescoImageViewer
  • Potentially larger library size due to multiple engine support

Code Comparison

FrescoImageViewer:

new ImageViewer.Builder<>(this, images)
    .setStartPosition(startPosition)
    .show();

BigImageViewer:

BigImageViewer bigImageViewer = findViewById(R.id.big_image_viewer);
bigImageViewer.setImageURI(Uri.parse("http://example.com/image.jpg"));

FrescoImageViewer focuses on simplicity and ease of use for displaying images in a gallery-like viewer. BigImageViewer offers more flexibility and advanced features, allowing developers to choose their preferred image loading engine and customize the viewing experience. While FrescoImageViewer may be quicker to implement for basic use cases, BigImageViewer provides more control and optimization options for complex scenarios involving large images or specific performance requirements.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

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 to the StfalconImageViewer which is a better version of the FrescoImageViewer. Otherwise, you can still use the latest version of this library. Anyway, PRs are welcome!

FrescoImageViewer

codebeat badge Download

Simple customizable full screen image viewer for Fresco library that includes "pinch to zoom" and "swipe to dismiss" gestures. Based on PhotoDraweeView by ongakuer.

alt tag

Who we are

Need iOS and Android apps, MVP development or prototyping? Contact us via info@stfalcon.com. We develop software since 2009, and we're known experts in this field. Check out our portfolio and see more libraries from stfalcon-studio.

Requirements

  • Fresco v.0.12.0 and higher
  • SDK 14 and and higher

Demo Application

Get it on Google Play

Usage

Simple usage

All you need to show a viewer is pass the context, start position and List or String[] into builder and call show().

new ImageViewer.Builder(context, list)
        .setStartPosition(startPosition)
        .show();

Custom objects

But what if in your application images are represented not only with urls? For example, you have object with url and description? You'll have to convert it to list of Strings and only then pass it to viewer, right? No, it's unnecessary! With ImageViewer.Formatter you can pass list of your custom images to viewer and simply write a rule for url extracting:

List<CustomImage> images = getImages();
new ImageViewer.Builder<>(this, images)
        .setFormatter(new ImageViewer.Formatter<CustomImage>() {
            @Override
            public String format(CustomImage customImage) {
                return customImage.getUrl();
            }
        })
        .show();

If formatter isn't passed, Object.toString() will be used for image formatting as default behavior.

Piece of cake! :cake: :wink:

Reminder

Don't forget to initialize Fresco in your Application class:

Fresco.initialize(this);

And if you expect to open really large images, use configuration below for better performance:

ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)
    .setProgressiveJpegConfig(new SimpleProgressiveJpegConfig())
    .setResizeAndRotateEnabledForNetwork(true)
    .setDownsampleEnabled(true)
    .build();
Fresco.initialize(this, config);

Customizing

You can also customize a viewer to fit your needs.

Background

Use setBackgroundColorRes(colorRes) or setBackgroundColor(colorInt) to set color for fading background.

Custom overlay view

If you need some content over the image (e.g. sharing or download button, description, numeration etc.) you can set your custom view using setOverlayView(customView) and bind it with viewer through ImageViewer.OnImageChangeListener.

Custom drawee hierarchy

Of course, according to Fresco flexibility, you can use your custom GenericDraweeHierarchy. To do this you simply need to create GenericDraweeHierarchyBuilder and pass it into builder:

GenericDraweeHierarchyBuilder hierarchyBuilder = GenericDraweeHierarchyBuilder.newInstance(getResources())
        .setFailureImage(R.drawable.failureDrawable)
        .setProgressBarImage(R.drawable.progressBarDrawable)
        .setPlaceholderImage(R.drawable.placeholderDrawable);

builder.setCustomDraweeHierarchyBuilder(hierarchyBuilder)

:exclamation:But there is a limitation: default ScaleType in hierarchy is ScaleType.FIT_CENTER, so custom value will be ignored

Custom image requests

For rare cases like post-processing or bitmap resizing you need to use your custom ImageRequestBuilder. Create it with ImageViewer.createImageRequestBuilder() and after configuration pass it to viewer through setCustomImageRequestBuilder(ImageRequestBuilder).

builder.setCustomImageRequestBuilder(
            ImageViewer.createImageRequestBuilder()
                    .setPostprocessor(new GrayscalePostprocessor()));

Image margin

Simply add margins between images with dimens with setImageMargin(context, dimen) or in px using setImageMarginPx(marginPx).

Container padding

Overlay image hides part of image? Set container padding with dimens using setContainerPadding(context, start, top, end, bottom) or setContainerPadding(context, dimean) for all sides at once. For setting padding in pixels, just use setContainerPaddingPx(...) method.

Status bar visibility

To show/hide status bar in view property you can set hideStatusBar(boolean) in builder. The default value is true.

Gestures disabling

If you need to disable some of gestures - do it using allowSwipeToDismiss(boolean) and allowZooming(boolean) accordingly.

Here is an example that sets all the possible options:

new ImageViewer.Builder<>(this, images)
        .setStartPosition(startPosition)
        .hideStatusBar(false)
        .allowZooming(true)
        .allowSwipeToDismiss(true)
        .setBackgroundColorRes(colorRes)
        //.setBackgroundColor(color)
        .setImageMargin(margin)
        //.setImageMarginPx(marginPx)
        .setContainerPadding(this, dimen)
        //.setContainerPadding(this, dimenStart, dimenTop, dimenEnd, dimenBottom)
        //.setContainerPaddingPx(padding)
        //.setContainerPaddingPx(start, top, end, bottom)
        .setCustomImageRequestBuilder(imageRequestBuilder)
        .setCustomDraweeHierarchyBuilder(draweeHierarchyBuilder)
        .setImageChangeListener(imageChangeListener)
        .setOnDismissListener(onDismissListener)
        .setOverlayView(overlayView)
        .show();

With this possibilities you can achieve something like this:

alt tag

You can take a look at sample project for more information.

Install

Download via Gradle:

compile 'com.github.stfalcon:frescoimageviewer:0.5.0'

or Maven:

<dependency>
  <groupId>com.github.stfalcon</groupId>
  <artifactId>frescoimageviewer</artifactId>
  <version>0.5.0</version>
  <type>pom</type>
</dependency>

Changelog

See the changelog to be aware of latest improvements and fixes.

License

Copyright (C) 2017 stfalcon.com

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.