Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add this doc to wiki #331

Closed
HR opened this issue Jun 24, 2017 · 5 comments
Closed

Add this doc to wiki #331

HR opened this issue Jun 24, 2017 · 5 comments

Comments

@HR
Copy link

HR commented Jun 24, 2017

Since many have already asked the question of how to get a Bitmap of the visible region, I have written the following docs after figuring it out myself. Please add it to the wiki so it can help others :)


--- Rendered ---

Getting a Bitmap of the visible region

You can obtain a Bitmap of the current visible region (in the image view) of the source image by using the viewToSourceCoord for each diagonal coordinate of the rectangular image view (e.g. top left and bottom right) in order to map the view coordinates to the source image coordinates. Forming a Rect from the result, the BitmapRegionDecoder can then be used to decode the visible region to a rectangular Bitmap.

SubsamplingScaleImageView imageView = (SubsamplingScaleImageView)findViewById(id.imageView);

// Get visible region source coordinates
PointF leftTopCoord = imageView.viewToSourceCoord(new PointF(0, 0));
PointF rightBottomCoord = imageView.viewToSourceCoord(new PointF(imageView.getWidth(), imageView.getHeight()));

// Create visible region rectangle from source coordinates
RectF visibleRectF = new RectF(leftTopCoord.x, leftTopCoord.y, rightBottomCoord.x, rightBottomCoord.y);
final Rect visibleRect = new Rect();

// Convert RectF to Rect (as required by BitmapRegionDecoder)
visibleRectF.round(visibleRect);

BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(sourceImageFileStream, false);

// Decode the visible region to a Bitmap
Bitmap visibleWallBitmap = decoder.decodeRegion(visibleRect, null);

Note that when the image is zoomed out and has a border, converting a view coordinate that is in the border will return a source coordinate that isn't valid (either a negative x or y coordinate, or an x/y coordinate greater than the width/height of the image) and could cause decode failure.

--- Raw ---

### Getting a Bitmap of the visible region

You can obtain a Bitmap of the current visible region (in the image view) of the source image by using the `viewToSourceCoord` for each diagonal coordinate of the rectangular image view (e.g. top left and bottom right) in order to map the view coordinates to the source image coordinates. Forming a `Rect` from the result, the [BitmapRegionDecoder](https://developer.android.com/reference/android/graphics/BitmapRegionDecoder.html) can then be used to decode the visible region to a rectangular Bitmap.

```java
SubsamplingScaleImageView imageView = (SubsamplingScaleImageView)findViewById(id.imageView);

// Get visible region source coordinates
PointF leftTopCoord = imageView.viewToSourceCoord(new PointF(0, 0));
PointF rightBottomCoord = imageView.viewToSourceCoord(new PointF(imageView.getWidth(), imageView.getHeight()));

// Create visible region rectangle from source coordinates
RectF visibleRectF = new RectF(leftTopCoord.x, leftTopCoord.y, rightBottomCoord.x, rightBottomCoord.y);
final Rect visibleRect = new Rect();

// Convert RectF to Rect (as required by BitmapRegionDecoder)
visibleRectF.round(visibleRect);

BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(sourceImageFileStream, false);

// Decode the visible region to a Bitmap
Bitmap visibleWallBitmap = decoder.decodeRegion(visibleRect, null);
**Note that** when the image is zoomed out and has a border, converting a view coordinate that is in the border will return a source coordinate that isn't valid (either a negative x or y coordinate, or an x/y coordinate greater than the width/height of the image) and could cause decode failure.
@davemorrissey
Copy link
Owner

Looks good, thanks! However I think it would make sense to add a getVisibleRect or viewToSourceRect method to the class which would make this much easier, so I'll try to find some time to do that.

@HR
Copy link
Author

HR commented Jun 25, 2017

Great! There was a viewToSourceRect method a time ago but was removed in 757552d

@HR
Copy link
Author

HR commented Jun 25, 2017

Just bring it back 😉

@davemorrissey
Copy link
Owner

Yeah it was private, and I refactored the class to re-use Rect and Point instances.

davemorrissey added a commit that referenced this issue Nov 9, 2017
… to simplify extracting the visible area from an image.
@davemorrissey
Copy link
Owner

I've added viewToFileRect and visibleFileRect methods which will return a rectangle from the source file that correctly takes into account the image orientation, the region displayed, and the actual width and height of the file.

Methods that return source coordinates don't take these into account so the old viewToSourceRect method wasn't suitable for this purpose. It does work fine if you're displaying the whole image in its native orientation, and only then because BitmapRegionDecoder handles negative coordinates.

I'll write a wiki article once this is released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants