diff options
6 files changed, 175 insertions, 11 deletions
diff --git a/library/src/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java b/library/src/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java index 3a484e3..1afcee2 100644 --- a/library/src/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java +++ b/library/src/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java @@ -165,6 +165,8 @@ public class SubsamplingScaleImageView extends View { private int sWidth; private int sHeight; private int sOrientation; + private Rect sRegion; + private Rect pRegion; // Is two-finger zooming in progress private boolean isZooming; @@ -350,6 +352,7 @@ public class SubsamplingScaleImageView extends View { } this.sWidth = imageSource.getSWidth(); this.sHeight = imageSource.getSHeight(); + this.pRegion = previewSource.getSRegion(); if (previewSource.getBitmap() != null) { onPreviewLoaded(previewSource.getBitmap()); } else { @@ -362,15 +365,17 @@ public class SubsamplingScaleImageView extends View { } } - if (imageSource.getBitmap() != null) { - // Display the image as it is. + if (imageSource.getBitmap() != null && imageSource.getSRegion() != null) { + onPreviewLoaded(Bitmap.createBitmap(imageSource.getBitmap(), imageSource.getSRegion().left, imageSource.getSRegion().top, imageSource.getSRegion().width(), imageSource.getSRegion().height())); + } else if (imageSource.getBitmap() != null) { onImageLoaded(imageSource.getBitmap(), ORIENTATION_0); } else { + this.sRegion = imageSource.getSRegion(); Uri uri = imageSource.getUri(); if (uri == null && imageSource.getResource() != null) { uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + getContext().getPackageName() + "/" + imageSource.getResource()); } - if (imageSource.getTile()) { + if (imageSource.getTile() || this.sRegion != null) { // Load the bitmap using tile decoding. TilesInitTask task = new TilesInitTask(this, getContext(), regionDecoderClass, uri); task.execute(); @@ -421,6 +426,8 @@ public class SubsamplingScaleImageView extends View { sWidth = 0; sHeight = 0; sOrientation = 0; + sRegion = null; + pRegion = null; readySent = false; imageLoadedSent = false; bitmap = null; @@ -1294,8 +1301,14 @@ public class SubsamplingScaleImageView extends View { if (context != null && decoderClass != null && view != null) { decoder = decoderClass.newInstance(); Point dimensions = decoder.init(context, source); + int sWidth = dimensions.x; + int sHeight = dimensions.y; int exifOrientation = view.getExifOrientation(sourceUri); - return new int[] { dimensions.x, dimensions.y, exifOrientation }; + if (view.sRegion != null) { + sWidth = view.sRegion.width(); + sHeight = view.sRegion.height(); + } + return new int[] { sWidth, sHeight, exifOrientation }; } } catch (Exception e) { Log.e(TAG, "Failed to initialise bitmap decoder", e); @@ -1366,6 +1379,9 @@ public class SubsamplingScaleImageView extends View { synchronized (view.decoderLock) { // Update tile's file sRect according to rotation view.fileSRect(tile.sRect, tile.fileSRect); + if (view.sRegion != null) { + tile.fileSRect.offset(view.sRegion.left, view.sRegion.top); + } Bitmap bitmap = decoder.decodeRegion(tile.fileSRect, tile.sampleSize); int rotation = view.getRequiredRotation(); if (rotation != 0) { @@ -1485,13 +1501,17 @@ public class SubsamplingScaleImageView extends View { /** * Called by worker task when preview image is loaded. */ - private synchronized void onPreviewLoaded(Bitmap bitmap) { - if (this.bitmap != null || imageLoadedSent) { - bitmap.recycle(); + private synchronized void onPreviewLoaded(Bitmap previewBitmap) { + if (bitmap != null || imageLoadedSent) { + previewBitmap.recycle(); return; } - this.preview = true; - this.bitmap = bitmap; + if (pRegion != null) { + bitmap = Bitmap.createBitmap(previewBitmap, pRegion.left, pRegion.top, pRegion.width(), pRegion.height()); + } else { + bitmap = previewBitmap; + } + preview = true; if (checkReady()) { invalidate(); requestLayout(); diff --git a/sample/res/layout/imagedisplay_region_fragment.xml b/sample/res/layout/imagedisplay_region_fragment.xml new file mode 100644 index 0000000..b9367ba --- /dev/null +++ b/sample/res/layout/imagedisplay_region_fragment.xml @@ -0,0 +1,73 @@ +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/content" + android:layout_width="match_parent" + android:layout_height="match_parent" > + + <RelativeLayout + android:id="@+id/text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:background="#333"> + <ImageView + android:id="@+id/previous" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true" + android:layout_centerVertical="true" + android:background="@drawable/buttonstate_transparent" + android:paddingLeft="8dp" + android:paddingRight="8dp" + android:paddingTop="18dp" + android:paddingBottom="18dp" + android:src="@drawable/previous"/> + + <ImageView + android:id="@+id/next" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentRight="true" + android:layout_centerVertical="true" + android:background="@drawable/buttonstate_transparent" + android:visibility="invisible" + android:paddingLeft="8dp" + android:paddingRight="8dp" + android:paddingTop="18dp" + android:paddingBottom="18dp" + android:src="@drawable/next"/> + + <ImageView + android:id="@+id/rotate" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_toLeftOf="@id/next" + android:layout_centerVertical="true" + android:background="@drawable/buttonstate_transparent" + android:paddingLeft="8dp" + android:paddingRight="8dp" + android:paddingTop="18dp" + android:paddingBottom="18dp" + android:src="@drawable/rotate"/> + + <TextView + android:id="@+id/note" + android:layout_height="wrap_content" + android:layout_width="match_parent" + android:layout_toLeftOf="@id/rotate" + android:layout_toRightOf="@id/previous" + android:layout_centerVertical="true" + android:text="Set the region to display instead of the whole image." + android:padding="10dp" + android:textSize="14sp" + android:textColor="#FFFFFF"/> + + </RelativeLayout> + + <com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView + android:id="@+id/imageView" + android:layout_alignParentTop="true" + android:layout_above="@+id/text" + android:layout_width="match_parent" + android:layout_height="match_parent"/> + +</RelativeLayout>
\ No newline at end of file diff --git a/sample/res/layout/imagedisplay_rotate_fragment.xml b/sample/res/layout/imagedisplay_rotate_fragment.xml index 67e939b..f84524a 100644 --- a/sample/res/layout/imagedisplay_rotate_fragment.xml +++ b/sample/res/layout/imagedisplay_rotate_fragment.xml @@ -29,7 +29,6 @@ android:layout_alignParentRight="true" android:layout_centerVertical="true" android:background="@drawable/buttonstate_transparent" - android:visibility="invisible" android:paddingLeft="8dp" android:paddingRight="8dp" android:paddingTop="18dp" diff --git a/sample/src/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayActivity.java b/sample/src/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayActivity.java index a92d5d4..79142fd 100644 --- a/sample/src/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayActivity.java +++ b/sample/src/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayActivity.java @@ -47,7 +47,8 @@ public class ImageDisplayActivity extends FragmentActivity { } pages = Arrays.asList( new Page("Large images", ImageDisplayLargeFragment.class), - new Page("Rotation", ImageDisplayRotateFragment.class) + new Page("Rotation", ImageDisplayRotateFragment.class), + new Page("Display region", ImageDisplayRegionFragment.class) ); updatePage(); diff --git a/sample/src/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayRegionFragment.java b/sample/src/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayRegionFragment.java new file mode 100644 index 0000000..02f4b65 --- /dev/null +++ b/sample/src/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayRegionFragment.java @@ -0,0 +1,65 @@ +/* +Copyright 2014 David Morrissey + +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. +*/ + +package com.davemorrissey.labs.subscaleview.sample.imagedisplay; + +import android.graphics.Rect; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; +import com.davemorrissey.labs.subscaleview.sample.R.id; +import com.davemorrissey.labs.subscaleview.sample.R.layout; + +import java.util.Random; + +public class ImageDisplayRegionFragment extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View rootView = inflater.inflate(layout.imagedisplay_region_fragment, container, false); + final SubsamplingScaleImageView imageView = (SubsamplingScaleImageView)rootView.findViewById(id.imageView); + imageView.setImageAsset("squirrel.jpg", null, randomRegion(2456, 1632)); + rootView.findViewById(id.previous).setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + ((ImageDisplayActivity)getActivity()).previous(); + } + }); + rootView.findViewById(id.rotate).setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + imageView.setOrientation((imageView.getOrientation() + 90) % 360); + } + }); + + return rootView; + } + + private static Rect randomRegion(int width, int height) { + Random random = new Random(System.nanoTime()); + + int left = random.nextInt(width - 2); + int top = random.nextInt(height - 2); + int right = random.nextInt(width - left + 1) + left; + int bottom = random.nextInt(height - top + 1) + top; + + return new Rect(left, top, right, bottom); + } +} diff --git a/sample/src/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayRotateFragment.java b/sample/src/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayRotateFragment.java index b762aa8..e2f487d 100644 --- a/sample/src/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayRotateFragment.java +++ b/sample/src/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayRotateFragment.java @@ -45,6 +45,12 @@ public class ImageDisplayRotateFragment extends Fragment { ((ImageDisplayActivity)getActivity()).previous(); } }); + rootView.findViewById(id.next).setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + ((ImageDisplayActivity)getActivity()).next(); + } + }); rootView.findViewById(id.rotate).setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { |