mUpdateListeners
44 | = new ArrayList<>();
45 | private View mTarget;
46 | private long mStartTime;
47 | private long mDuration = 500;
48 | private float mFraction = 0f;
49 |
50 | private boolean mStarted = false;
51 | private boolean mEnded = false;
52 |
53 | private float mScaleStart;
54 | private float mScaleEnd;
55 | public PointF mSourceCenter;
56 |
57 | private PointF mViewFocusStart;
58 | private PointF mViewFocusEnd;
59 | private boolean mInterrupted = true;
60 | private Interpolator mScaleInterpolator;
61 | private Interpolator mTranslateInterpolator;
62 |
63 | public SimpleValueAnimator() {
64 | }
65 |
66 | public void setScaleStart(float scaleStart) {
67 | mScaleStart = scaleStart;
68 | }
69 |
70 | public void setScaleEnd(float scaleEnd) {
71 | mScaleEnd = scaleEnd;
72 | }
73 |
74 | public void setSourceCenter(PointF sourceCenter) {
75 | mSourceCenter = sourceCenter;
76 | }
77 |
78 | public void setViewFocusStart(PointF viewFocusStart) {
79 | mViewFocusStart = viewFocusStart;
80 | }
81 |
82 | public void setViewFocusEnd(PointF viewFocusEnd) {
83 | mViewFocusEnd = viewFocusEnd;
84 | }
85 |
86 | public void setInterrupted(boolean interrupted) {
87 | mInterrupted = interrupted;
88 | }
89 |
90 | public boolean isInterrupted() {
91 | return mInterrupted;
92 | }
93 |
94 | public void setScaleInterpolator(Interpolator scaleInterpolator) {
95 | mScaleInterpolator = scaleInterpolator;
96 | }
97 |
98 | public void setTranslateInterpolator(Interpolator translateInterpolator) {
99 | mTranslateInterpolator = translateInterpolator;
100 | }
101 |
102 | public float getScale(){
103 | return mScaleStart + mScaleInterpolator.getInterpolation(mFraction) * (mScaleEnd - mScaleStart);
104 | }
105 |
106 | public PointF getViewFocus(){
107 | float focusX = mViewFocusStart.x + mTranslateInterpolator.getInterpolation(mFraction) *
108 | (mViewFocusEnd.x - mViewFocusStart.x);
109 | float focusY = mViewFocusStart.y + mTranslateInterpolator.getInterpolation(mFraction) *
110 | (mViewFocusEnd.y - mViewFocusStart.y);
111 | return new PointF(focusX,focusY);
112 | }
113 |
114 | public boolean noChangeScale(){
115 | return mScaleStart == mScaleEnd;
116 | }
117 |
118 | private Runnable mLoopRunnable = new Runnable() {
119 | @Override
120 | public void run() {
121 | long dt = getTime() - mStartTime;
122 | float fraction = dt * 1f / mDuration;
123 | if (fraction > 1f || mTarget.getParent() == null) {
124 | fraction = 1f;
125 | }
126 | mFraction = fraction;
127 | notifyUpdateListeners();
128 | if (mFraction >= 1f) {
129 | mEnded = true;
130 | dispatchEnd();
131 | } else {
132 | mTarget.postDelayed(mLoopRunnable, 16);
133 | }
134 | }
135 | };
136 |
137 | private void notifyUpdateListeners() {
138 | for (int i = mUpdateListeners.size() - 1; i >= 0; i--) {
139 | mUpdateListeners.get(i).onAnimationUpdate(this);
140 | }
141 | }
142 |
143 | private void dispatchStart() {
144 | for (int i = mListeners.size() - 1; i >= 0; i--) {
145 | mListeners.get(i).onAnimationStart(this);
146 | }
147 | }
148 |
149 | private void dispatchEnd() {
150 | for (int i = mListeners.size() - 1; i >= 0; i--) {
151 | mListeners.get(i).onAnimationEnd(this);
152 | }
153 | }
154 |
155 | private void dispatchCancel() {
156 | for (int i = mListeners.size() - 1; i >= 0; i--) {
157 | mListeners.get(i).onAnimationCancel(this);
158 | }
159 | }
160 |
161 | private long getTime() {
162 | return System.currentTimeMillis();
163 | }
164 |
165 | @Override
166 | public void setTarget(View view) {
167 | mTarget = view;
168 | }
169 |
170 | @Override
171 | public void addListener(AnimatorListener listener) {
172 | mListeners.add(listener);
173 | }
174 |
175 | @Override
176 | public void setDuration(long duration) {
177 | if (!mStarted){
178 | mDuration = duration;
179 | }
180 | }
181 |
182 | public boolean isEnded() {
183 | return mEnded;
184 | }
185 |
186 | public boolean isStarted() {
187 | return mStarted;
188 | }
189 |
190 | @Override
191 | public void start() {
192 | if (mStarted){
193 | return;
194 | }
195 | mStarted = true;
196 | dispatchStart();
197 | mFraction = 0f;
198 | mStartTime = getTime();
199 | mTarget.postDelayed(mLoopRunnable,16);
200 | }
201 |
202 | @Override
203 | public void cancel() {
204 | if (mEnded){
205 | return;
206 | }
207 | mEnded = true;
208 | if (mStarted){
209 | dispatchCancel();
210 | }
211 | dispatchEnd();
212 | }
213 |
214 | @Override
215 | public void addUpdateListener(AnimatorUpdateListener animatorUpdateListener) {
216 | mUpdateListeners.add(animatorUpdateListener);
217 | }
218 |
219 | @Override
220 | public float getAnimatedFraction() {
221 | return mFraction;
222 | }
223 | }
224 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/animation/AnimatorListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.animation;
20 |
21 | /**
22 | * 文 件 名: AnimatorListener
23 | * 创 建 人: 陈志鹏
24 | * 创建日期: 2017/8/22 23:24
25 | * 邮 箱: ch_zh_p@qq.com
26 | * 修改时间:
27 | * 修改备注:
28 | */
29 |
30 | public interface AnimatorListener {
31 | /**
32 | * Notifies the start of the animation.
33 | *
34 | * @param animation The started animation.
35 | */
36 | void onAnimationStart(ValueAnimator animation);
37 |
38 | /**
39 | * Notifies the end of the animation. This callback is not invoked
40 | * for animations with repeat count set to INFINITE.
41 | *
42 | * @param animation The animation which reached its end.
43 | */
44 | void onAnimationEnd(ValueAnimator animation);
45 |
46 | /**
47 | * Notifies the cancellation of the animation. This callback is not invoked
48 | * for animations with repeat count set to INFINITE.
49 | *
50 | * @param animation The animation which was canceled.
51 | */
52 | void onAnimationCancel(ValueAnimator animation);
53 |
54 | /**
55 | * Notifies the repetition of the animation.
56 | *
57 | * @param animation The animation which was repeated.
58 | */
59 | void onAnimationRepeat(ValueAnimator animation);
60 | }
61 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/animation/AnimatorUpdateListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.animation;
20 |
21 | /**
22 | * 文 件 名: AnimatorUpdateListener
23 | * 创 建 人: 陈志鹏
24 | * 创建日期: 2017/8/22 23:25
25 | * 邮 箱: ch_zh_p@qq.com
26 | * 修改时间:
27 | * 修改备注:
28 | */
29 |
30 | public interface AnimatorUpdateListener {
31 |
32 | /**
33 | * Notifies the occurrence of another frame of the animation.
34 | *
35 | * @param animation The animation which was repeated.
36 | */
37 | void onAnimationUpdate(ValueAnimator animation);
38 | }
39 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/animation/ValueAnimator.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.animation;
20 |
21 | import android.view.View;
22 |
23 | /**
24 | * 文 件 名: SimpleValueAnimator
25 | * 创 建 人: 陈志鹏
26 | * 创建日期: 2017/8/22 23:23
27 | * 邮 箱: ch_zh_p@qq.com
28 | * 修改时间:
29 | * 修改备注:
30 | */
31 |
32 | public interface ValueAnimator {
33 | void setTarget(View view);
34 |
35 | void addListener(AnimatorListener listener);
36 |
37 | void setDuration(long duration);
38 |
39 | void start();
40 |
41 | void cancel();
42 |
43 | void addUpdateListener(AnimatorUpdateListener animatorUpdateListener);
44 |
45 | float getAnimatedFraction();
46 | }
47 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/core/HDImageViewConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.core;
20 |
21 | import android.content.Context;
22 | import android.graphics.Bitmap;
23 | import androidx.annotation.NonNull;
24 | import androidx.annotation.Nullable;
25 | import android.view.animation.DecelerateInterpolator;
26 | import android.view.animation.Interpolator;
27 |
28 | import java.lang.reflect.Constructor;
29 | import java.lang.reflect.InvocationTargetException;
30 | import java.util.ArrayList;
31 | import java.util.List;
32 |
33 | import xyz.zpayh.hdimage.datasource.Interceptor;
34 | import xyz.zpayh.hdimage.datasource.OrientationInterceptor;
35 | import xyz.zpayh.hdimage.datasource.interceptor.AssetInterceptor;
36 | import xyz.zpayh.hdimage.datasource.interceptor.AssetOrientationInterceptor;
37 | import xyz.zpayh.hdimage.datasource.interceptor.ContentInterceptor;
38 | import xyz.zpayh.hdimage.datasource.interceptor.ContentOrientationInterceptor;
39 | import xyz.zpayh.hdimage.datasource.interceptor.FileInterceptor;
40 | import xyz.zpayh.hdimage.datasource.interceptor.FileOrientationInterceptor;
41 | import xyz.zpayh.hdimage.datasource.interceptor.Interceptors;
42 | import xyz.zpayh.hdimage.datasource.interceptor.NetworkInterceptor;
43 | import xyz.zpayh.hdimage.datasource.interceptor.NetworkOrientationInterceptor;
44 | import xyz.zpayh.hdimage.datasource.interceptor.ResourceInterceptor;
45 | import xyz.zpayh.hdimage.util.Preconditions;
46 |
47 | /**
48 | * 文 件 名: HDImageViewConfig
49 | * 创 建 人: 陈志鹏
50 | * 创建日期: 2017/7/29 14:19
51 | * 邮 箱: ch_zh_p@qq.com
52 | * 修改时间:
53 | * 修改备注:
54 | */
55 |
56 | public class HDImageViewConfig {
57 | private static final String TAG = "HDImageViewConfig";
58 | private final Interpolator mScaleAnimationInterpolator;
59 | private final Interpolator mTranslationAnimationInterpolator;
60 |
61 | private final List mInterceptors;
62 | private final List mOrientationInterceptors;
63 | private final Bitmap.Config mBitmapConfig;
64 |
65 | public static Builder newBuilder(Context context){
66 | return new Builder(context);
67 | }
68 |
69 | private HDImageViewConfig(Builder builder){
70 | mBitmapConfig = builder.mBitmapConfig;
71 | mScaleAnimationInterpolator = builder.mScaleAnimationInterpolator == null ?
72 | new DecelerateInterpolator() : builder.mScaleAnimationInterpolator;
73 | mTranslationAnimationInterpolator = builder.mTranslationAnimationInterpolator == null ?
74 | new DecelerateInterpolator() : builder.mTranslationAnimationInterpolator;
75 |
76 | mInterceptors = new ArrayList<>();
77 |
78 |
79 | mInterceptors.add(new ResourceInterceptor(builder.mContext.getResources()));
80 | mInterceptors.add(new AssetInterceptor(builder.mContext.getAssets()));
81 | mInterceptors.add(new ContentInterceptor(builder.mContext));
82 | mInterceptors.add(new FileInterceptor());
83 |
84 | Interceptor glideInterceptor = addGlideInterceptor(builder.mContext);
85 | if (glideInterceptor != null){
86 | mInterceptors.add(glideInterceptor);
87 | }
88 |
89 | Interceptor frescoInterceptor = addFrescoInterceptor();
90 | if (frescoInterceptor != null){
91 | mInterceptors.add(frescoInterceptor);
92 | }
93 |
94 | if (glideInterceptor == null && frescoInterceptor == null) {
95 | mInterceptors.add(new NetworkInterceptor(builder.mContext));
96 | }
97 | mInterceptors.addAll(builder.mInterceptors);
98 |
99 | mOrientationInterceptors = new ArrayList<>();
100 | mOrientationInterceptors.addAll(builder.mOrientationInterceptors);
101 |
102 | mOrientationInterceptors.add(new AssetOrientationInterceptor());
103 | mOrientationInterceptors.add(new ContentOrientationInterceptor());
104 | mOrientationInterceptors.add(new FileOrientationInterceptor());
105 | mOrientationInterceptors.add(new NetworkOrientationInterceptor());
106 |
107 | //init
108 | Interceptors.initDiskLruCache(builder.mContext);
109 | }
110 |
111 | @Nullable
112 | @SuppressWarnings("unchecked")
113 | private Interceptor addGlideInterceptor(Context context){
114 | Interceptor interceptor = null;
115 | try {
116 | Class clazz =
117 | (Class) Class.forName("xyz.zpayh.hdimage.datasource.interceptor.GlideInterceptor");
118 | Constructor constructor = clazz.getConstructor(Context.class);
119 | interceptor = constructor.newInstance(context);
120 | } catch (ClassNotFoundException e) {
121 | } catch (NoSuchMethodException e) {
122 | } catch (InstantiationException e) {
123 | } catch (IllegalAccessException e) {
124 | } catch (InvocationTargetException e) {
125 | }
126 | return interceptor;
127 | }
128 |
129 | @Nullable
130 | @SuppressWarnings("unchecked")
131 | private Interceptor addFrescoInterceptor(){
132 | Interceptor interceptor = null;
133 |
134 | try {
135 | Class clazz =
136 | (Class) Class.forName("xyz.zpayh.hdimage.datasource.interceptor.FrescoInterceptor");
137 | interceptor = clazz.newInstance();
138 | } catch (ClassNotFoundException e) {
139 | } catch (InstantiationException e) {
140 | } catch (IllegalAccessException e) {
141 | }
142 | return interceptor;
143 | }
144 |
145 | public Interpolator getScaleAnimationInterpolator() {
146 | return mScaleAnimationInterpolator;
147 | }
148 |
149 | public Interpolator getTranslationAnimationInterpolator() {
150 | return mTranslationAnimationInterpolator;
151 | }
152 |
153 | public List getInterceptors() {
154 | return mInterceptors;
155 | }
156 |
157 | public List getOrientationInterceptors() {
158 | return mOrientationInterceptors;
159 | }
160 |
161 | public Bitmap.Config getBitmapConfig() {
162 | return mBitmapConfig;
163 | }
164 |
165 | public static class Builder {
166 | private Interpolator mScaleAnimationInterpolator;
167 | private Interpolator mTranslationAnimationInterpolator;
168 | private Context mContext;
169 | private List mInterceptors;
170 | private final List mOrientationInterceptors;
171 | private Bitmap.Config mBitmapConfig;
172 | private Builder(Context context){
173 | mContext = Preconditions.checkNotNull(context);
174 | mInterceptors = new ArrayList<>();
175 | mOrientationInterceptors = new ArrayList<>();
176 | mBitmapConfig = Bitmap.Config.RGB_565;
177 | }
178 |
179 | public Builder setBitmapConfig(@NonNull Bitmap.Config config) {
180 | mBitmapConfig = Preconditions.checkNotNull(config);
181 | return this;
182 | }
183 |
184 | public Builder setScaleAnimationInterpolator(Interpolator scaleAnimationInterpolator) {
185 | mScaleAnimationInterpolator = scaleAnimationInterpolator;
186 | return this;
187 | }
188 |
189 | public Builder setTranslationAnimationInterpolator(Interpolator translationAnimationInterpolator) {
190 | mTranslationAnimationInterpolator = translationAnimationInterpolator;
191 | return this;
192 | }
193 |
194 | public Builder addInterceptor(Interceptor interceptor){
195 | mInterceptors.add(interceptor);
196 | return this;
197 | }
198 |
199 | public Builder addOrientationInterceptor(OrientationInterceptor interceptor){
200 | mOrientationInterceptors.add(interceptor);
201 | return this;
202 | }
203 |
204 | public HDImageViewConfig build(){
205 | return new HDImageViewConfig(this);
206 | }
207 | }
208 | }
209 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/core/HDImageViewFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.core;
20 |
21 | import android.content.Context;
22 | import android.graphics.Bitmap;
23 | import android.view.animation.Interpolator;
24 |
25 | import java.util.List;
26 |
27 | import xyz.zpayh.hdimage.datasource.Interceptor;
28 | import xyz.zpayh.hdimage.datasource.OrientationInterceptor;
29 | import xyz.zpayh.hdimage.util.Preconditions;
30 |
31 | /**
32 | * 文 件 名: HDImageViewFactory
33 | * 创 建 人: 陈志鹏
34 | * 创建日期: 2017/7/29 14:08
35 | * 邮 箱: ch_zh_p@qq.com
36 | * 修改时间:
37 | * 修改备注:
38 | */
39 |
40 | public class HDImageViewFactory {
41 | private static HDImageViewFactory sInstance = null;
42 |
43 | private static HDImageViewFactory sDefaultInstance = null;
44 |
45 | public static HDImageViewFactory getInstance(){
46 | if (sInstance == null){
47 | return Preconditions.checkNotNull(sDefaultInstance, "Default HDImageViewFactory was not initialized!");
48 | }
49 | return sInstance;
50 | }
51 |
52 | public static void initializeDefault(Context context){
53 | if (sDefaultInstance == null){
54 | synchronized (HDImageViewFactory.class){
55 | if (sDefaultInstance == null){
56 | sDefaultInstance = new HDImageViewFactory(HDImageViewConfig.newBuilder(context.getApplicationContext()).build());
57 | }
58 | }
59 | }
60 | }
61 |
62 | public static void initialize(Context context){
63 | initialize(HDImageViewConfig.newBuilder(context.getApplicationContext()).build());
64 | }
65 |
66 | public static void initialize(HDImageViewConfig config){
67 | sInstance = new HDImageViewFactory(config);
68 | }
69 |
70 | private final HDImageViewConfig mConfig;
71 |
72 | public HDImageViewFactory(HDImageViewConfig config){
73 | mConfig = Preconditions.checkNotNull(config);
74 | }
75 |
76 | public Interpolator getScaleAnimationInterpolator() {
77 | return mConfig.getScaleAnimationInterpolator();
78 | }
79 |
80 | public Interpolator getTranslationAnimationInterpolator() {
81 | return mConfig.getTranslationAnimationInterpolator();
82 | }
83 |
84 | public List getDataSourceInterceptor(){
85 | return mConfig.getInterceptors();
86 | }
87 |
88 | public List getOrientationInterceptor() {
89 | return mConfig.getOrientationInterceptors();
90 | }
91 |
92 | public Bitmap.Config getBitmapConfig() {
93 | return mConfig.getBitmapConfig();
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/BitmapDataSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.datasource;
20 |
21 | import android.content.Context;
22 | import android.graphics.Bitmap;
23 | import android.graphics.Point;
24 | import android.graphics.Rect;
25 | import android.net.Uri;
26 | import androidx.annotation.NonNull;
27 |
28 | import xyz.zpayh.hdimage.state.Orientation;
29 |
30 | /**
31 | * 文 件 名: BitmapDataSource
32 | * 创 建 人: 陈志鹏
33 | * 创建日期: 2017/4/1 17:21
34 | * 邮 箱: ch_zh_p@qq.com
35 | * 修改时间:
36 | * 修改备注:
37 | */
38 |
39 | public interface BitmapDataSource {
40 |
41 | String FILE_SCHEME = "file://";
42 | String ASSET_SCHEME = "asset:///";
43 | String RESOURCE_SCHEME = "res://";
44 | String HTTP_SCHEME = "http://";
45 | String HTTPS_SCHEME = "https://";
46 |
47 | void init(Context context, Uri uri, Point dimensions, OnInitListener listener);
48 |
49 | Bitmap decode(Rect sRect, int sampleSize);
50 |
51 | boolean isReady();
52 |
53 | void recycle();
54 |
55 | @Orientation
56 | int getExifOrientation(@NonNull Context context, String sourceUri);
57 |
58 | interface OnInitListener{
59 | void success();
60 |
61 | void failed(Throwable throwable);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/DefaultBitmapDataSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.datasource;
20 |
21 | import android.content.Context;
22 | import android.graphics.Bitmap;
23 | import android.graphics.BitmapFactory;
24 | import android.graphics.BitmapRegionDecoder;
25 | import android.graphics.Point;
26 | import android.graphics.Rect;
27 | import android.net.Uri;
28 | import androidx.annotation.NonNull;
29 |
30 | import java.io.IOException;
31 |
32 | import xyz.zpayh.hdimage.core.HDImageViewFactory;
33 |
34 | /**
35 | * 文 件 名: DefaultBitmapDataSource
36 | * 创 建 人: 陈志鹏
37 | * 创建日期: 2017/7/29 13:26
38 | * 邮 箱: ch_zh_p@qq.com
39 | * 修改时间:
40 | * 修改备注:
41 | */
42 |
43 | public class DefaultBitmapDataSource implements BitmapDataSource{
44 |
45 | private BitmapRegionDecoder mDecoder;
46 | private final Object mDecoderLock = new Object();
47 | private OrientationInterceptor mOrientationInterceptor;
48 |
49 | @Override
50 | public void init(Context context, Uri uri, Point dimensions, OnInitListener listener) {
51 |
52 | try {
53 | mDecoder = getDecoderWithInterceptorChain(uri);
54 | if (mDecoder != null) {
55 | if (dimensions != null){
56 | dimensions.set(mDecoder.getWidth(), mDecoder.getHeight());
57 | }
58 | if (listener != null){
59 | listener.success();
60 | }
61 | }else{
62 | if (listener != null){
63 | listener.failed(new IOException("init failed"));
64 | }
65 | }
66 | } catch (IOException e) {
67 | e.printStackTrace();
68 | if (listener != null){
69 | listener.failed(e);
70 | }
71 | }
72 | }
73 |
74 | @Override
75 | public Bitmap decode(Rect sRect, int sampleSize) {
76 | if (mDecoder == null){
77 | return null;
78 | }
79 | synchronized (mDecoderLock) {
80 | BitmapFactory.Options options = new BitmapFactory.Options();
81 | options.inSampleSize = sampleSize;
82 | // Default RGB_565
83 | options.inPreferredConfig = HDImageViewFactory.getInstance().getBitmapConfig();
84 | return mDecoder.decodeRegion(sRect, options);
85 | }
86 | }
87 |
88 | @Override
89 | public boolean isReady() {
90 | return mDecoder != null && !mDecoder.isRecycled();
91 | }
92 |
93 | @Override
94 | public void recycle() {
95 | if (mDecoder != null) {
96 | mDecoder.recycle();
97 | }
98 | }
99 |
100 | @Override
101 | public int getExifOrientation(@NonNull Context context, String sourceUri) {
102 | if (mOrientationInterceptor == null) {
103 | mOrientationInterceptor = new RealOrientationInterceptor(HDImageViewFactory.getInstance().getOrientationInterceptor());
104 | }
105 | return mOrientationInterceptor.getExifOrientation(context, sourceUri);
106 | }
107 |
108 | private BitmapRegionDecoder getDecoderWithInterceptorChain(Uri uri) throws IOException{
109 | Interceptor.Chain chain = new RealInterceptorChain(HDImageViewFactory.getInstance().getDataSourceInterceptor(),0,uri);
110 | return chain.chain(uri);
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/Interceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.datasource;
20 |
21 | import android.graphics.BitmapRegionDecoder;
22 | import android.net.Uri;
23 |
24 | import java.io.IOException;
25 |
26 | /**
27 | * 文 件 名: Interceptor
28 | * 创 建 人: 陈志鹏
29 | * 创建日期: 2017/7/29 16:31
30 | * 邮 箱: ch_zh_p@qq.com
31 | * 修改时间:
32 | * 修改备注:
33 | */
34 |
35 | public interface Interceptor {
36 | BitmapRegionDecoder intercept(Chain chain) throws IOException;
37 |
38 | interface Chain {
39 |
40 | Uri uri();
41 |
42 | BitmapRegionDecoder chain(Uri uri) throws IOException;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/OrientationInterceptor.java:
--------------------------------------------------------------------------------
1 | package xyz.zpayh.hdimage.datasource;
2 |
3 | import android.content.Context;
4 | import androidx.annotation.NonNull;
5 |
6 | import xyz.zpayh.hdimage.state.Orientation;
7 |
8 | public interface OrientationInterceptor {
9 | @Orientation
10 | int getExifOrientation(@NonNull Context context, String sourceUri);
11 | }
12 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/RealInterceptorChain.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.datasource;
20 |
21 | import android.graphics.BitmapRegionDecoder;
22 | import android.net.Uri;
23 |
24 | import java.io.IOException;
25 | import java.util.List;
26 |
27 | /**
28 | * 文 件 名: RealInterceptorChain
29 | * 创 建 人: 陈志鹏
30 | * 创建日期: 2017/7/29 17:03
31 | * 邮 箱: ch_zh_p@qq.com
32 | * 修改时间:
33 | * 修改备注:
34 | */
35 |
36 | public final class RealInterceptorChain implements Interceptor.Chain {
37 |
38 | private final List mInterceptors;
39 | private final int mIndex;
40 | private final Uri mUri;
41 |
42 | RealInterceptorChain(List interceptors, int index, Uri uri) {
43 | mInterceptors = interceptors;
44 | mIndex = index;
45 | mUri = uri;
46 | }
47 |
48 | @Override
49 | public Uri uri() {
50 | return mUri;
51 | }
52 |
53 | @Override
54 | public BitmapRegionDecoder chain(Uri uri) throws IOException{
55 | if (mIndex >= mInterceptors.size()) {
56 | return null;
57 | }
58 |
59 | RealInterceptorChain next = new RealInterceptorChain(mInterceptors,mIndex+1,uri);
60 | Interceptor interceptor = mInterceptors.get(mIndex);
61 |
62 | return interceptor.intercept(next);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/RealOrientationInterceptor.java:
--------------------------------------------------------------------------------
1 | package xyz.zpayh.hdimage.datasource;
2 |
3 | import android.content.Context;
4 | import androidx.annotation.NonNull;
5 |
6 | import java.util.List;
7 |
8 | import xyz.zpayh.hdimage.state.Orientation;
9 |
10 | public class RealOrientationInterceptor implements OrientationInterceptor{
11 |
12 | private final List mInterceptors;
13 |
14 | RealOrientationInterceptor(List interceptors) {
15 | mInterceptors = interceptors;
16 | }
17 |
18 | @Override
19 | public int getExifOrientation(@NonNull Context context, String sourceUri) {
20 | for (OrientationInterceptor interceptor : mInterceptors) {
21 | int orientation = interceptor.getExifOrientation(context, sourceUri);
22 | if (orientation != Orientation.ORIENTATION_EXIF) {
23 | return orientation;
24 | }
25 | }
26 | return Orientation.ORIENTATION_0;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/interceptor/AssetInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.datasource.interceptor;
20 |
21 | import android.content.res.AssetManager;
22 | import android.graphics.BitmapRegionDecoder;
23 | import android.net.Uri;
24 | import android.util.Log;
25 |
26 | import java.io.IOException;
27 | import java.io.InputStream;
28 |
29 | import xyz.zpayh.hdimage.BuildConfig;
30 | import xyz.zpayh.hdimage.datasource.Interceptor;
31 | import xyz.zpayh.hdimage.util.UriUtil;
32 |
33 | /**
34 | * 文 件 名: AssetInterceptor
35 | * 创 建 人: 陈志鹏
36 | * 创建日期: 2017/7/29 17:28
37 | * 邮 箱: ch_zh_p@qq.com
38 | * 修改时间:
39 | * 修改备注:
40 | */
41 |
42 | public class AssetInterceptor implements Interceptor{
43 |
44 | private final AssetManager mAssetManager;
45 |
46 | public AssetInterceptor(AssetManager assetManager) {
47 | mAssetManager = assetManager;
48 | }
49 |
50 | @Override
51 | public BitmapRegionDecoder intercept(Chain chain) throws IOException {
52 | final Uri uri = chain.uri();
53 | BitmapRegionDecoder decoder = chain.chain(uri);
54 | if (decoder != null){
55 | return decoder;
56 | }
57 |
58 | if (UriUtil.isLocalAssetUri(uri)){
59 | if (BuildConfig.DEBUG) {
60 | Log.d("AssetInterceptor", "从我这加载");
61 | }
62 | try {
63 | InputStream inputStream = mAssetManager.open(getAssetName(uri),AssetManager.ACCESS_STREAMING);
64 | return BitmapRegionDecoder.newInstance(inputStream,false);
65 | } catch (IOException e) {
66 | InputStream inputStream = mAssetManager.open(getAssetName(uri),AssetManager.ACCESS_STREAMING);
67 | return Interceptors.fixJPEGDecoder(inputStream,uri,e);
68 | //e.printStackTrace();
69 | }
70 | }
71 | return null;
72 | }
73 |
74 | private static String getAssetName(Uri uri) {
75 | return uri.getPath().substring(1);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/interceptor/AssetOrientationInterceptor.java:
--------------------------------------------------------------------------------
1 | package xyz.zpayh.hdimage.datasource.interceptor;
2 |
3 | import android.content.Context;
4 | import android.content.res.AssetManager;
5 | import androidx.annotation.NonNull;
6 | import androidx.exifinterface.media.ExifInterface;
7 |
8 | import java.io.IOException;
9 |
10 | import xyz.zpayh.hdimage.datasource.OrientationInterceptor;
11 | import xyz.zpayh.hdimage.state.Orientation;
12 |
13 | import static xyz.zpayh.hdimage.datasource.BitmapDataSource.ASSET_SCHEME;
14 |
15 | public class AssetOrientationInterceptor implements OrientationInterceptor {
16 | @Override
17 | public int getExifOrientation(@NonNull Context context, String sourceUri) {
18 | if (sourceUri.startsWith(ASSET_SCHEME)) {
19 | try {
20 | String assetName = sourceUri.substring(ASSET_SCHEME.length());
21 | ExifInterface exifInterface = new ExifInterface(context.getAssets().open(assetName, AssetManager.ACCESS_RANDOM));
22 | int orientationAttr = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);
23 | switch (orientationAttr) {
24 | case ExifInterface.ORIENTATION_NORMAL:
25 | case ExifInterface.ORIENTATION_UNDEFINED:
26 | return Orientation.ORIENTATION_0;
27 | case ExifInterface.ORIENTATION_ROTATE_90:
28 | return Orientation.ORIENTATION_90;
29 | case ExifInterface.ORIENTATION_ROTATE_180:
30 | return Orientation.ORIENTATION_180;
31 | case ExifInterface.ORIENTATION_ROTATE_270:
32 | return Orientation.ORIENTATION_270;
33 | }
34 | } catch (IOException e) {
35 | e.printStackTrace();
36 | }
37 | }
38 | return Orientation.ORIENTATION_EXIF;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/interceptor/ContentInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.datasource.interceptor;
20 |
21 | import android.content.ContentResolver;
22 | import android.content.Context;
23 | import android.graphics.BitmapRegionDecoder;
24 | import android.net.Uri;
25 |
26 | import java.io.IOException;
27 | import java.io.InputStream;
28 |
29 | import xyz.zpayh.hdimage.datasource.Interceptor;
30 | import xyz.zpayh.hdimage.util.Preconditions;
31 | import xyz.zpayh.hdimage.util.UriUtil;
32 |
33 | /**
34 | * 文 件 名: ContentInterceptor
35 | * 创 建 人: 陈志鹏
36 | * 创建日期: 2017/7/30 20:07
37 | * 邮 箱: ch_zh_p@qq.com
38 | * 修改时间:
39 | * 修改备注:
40 | */
41 |
42 | public class ContentInterceptor implements Interceptor {
43 |
44 | private final Context mContext;
45 |
46 | public ContentInterceptor(Context context) {
47 | mContext = Preconditions.checkNotNull(context);
48 | }
49 |
50 | @Override
51 | public BitmapRegionDecoder intercept(Chain chain) throws IOException {
52 | final Uri uri = chain.uri();
53 | BitmapRegionDecoder decoder = chain.chain(uri);
54 | if (decoder != null){
55 | return decoder;
56 | }
57 |
58 | if (UriUtil.isLocalContentUri(uri) || UriUtil.isQualifiedResourceUri(uri)){
59 | InputStream inputStream = null;
60 | try {
61 | ContentResolver resolver = mContext.getContentResolver();
62 | try {
63 | inputStream = resolver.openInputStream(uri);
64 | decoder = BitmapRegionDecoder.newInstance(inputStream,false);
65 | } catch (IOException e) {
66 | //e.printStackTrace();
67 | inputStream = resolver.openInputStream(uri);
68 | return Interceptors.fixJPEGDecoder(inputStream,uri,e);
69 | }
70 | } finally {
71 | if (inputStream != null){
72 | try { inputStream.close(); }
73 | catch (Exception e){e.printStackTrace();}
74 | }
75 | }
76 | }
77 |
78 | return decoder;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/interceptor/ContentOrientationInterceptor.java:
--------------------------------------------------------------------------------
1 | package xyz.zpayh.hdimage.datasource.interceptor;
2 |
3 | import android.content.ContentResolver;
4 | import android.content.Context;
5 | import android.database.Cursor;
6 | import android.net.Uri;
7 | import android.provider.MediaStore;
8 | import androidx.annotation.NonNull;
9 |
10 | import xyz.zpayh.hdimage.datasource.OrientationInterceptor;
11 | import xyz.zpayh.hdimage.state.Orientation;
12 |
13 | import static xyz.zpayh.hdimage.state.Orientation.ORIENTATION_0;
14 | import static xyz.zpayh.hdimage.state.Orientation.ORIENTATION_180;
15 | import static xyz.zpayh.hdimage.state.Orientation.ORIENTATION_270;
16 | import static xyz.zpayh.hdimage.state.Orientation.ORIENTATION_90;
17 |
18 | public class ContentOrientationInterceptor implements OrientationInterceptor {
19 | @Override
20 | public int getExifOrientation(@NonNull Context context, String sourceUri) {
21 | if (sourceUri.startsWith(ContentResolver.SCHEME_CONTENT)) {
22 | final String[] columns = {MediaStore.Images.Media.ORIENTATION};
23 | final Cursor cursor = context.getContentResolver()
24 | .query(Uri.parse(sourceUri),columns,null,null,null);
25 | if (cursor != null){
26 | if (cursor.moveToFirst()){
27 | int orientation = cursor.getInt(0);
28 | if (orientation == ORIENTATION_0){
29 | return ORIENTATION_0;
30 | } else if (orientation == ORIENTATION_90){
31 | return ORIENTATION_90;
32 | } else if (orientation == ORIENTATION_180){
33 | return ORIENTATION_180;
34 | } else if (orientation == ORIENTATION_270){
35 | return ORIENTATION_270;
36 | }
37 | }
38 | cursor.close();
39 | }
40 | }
41 | return Orientation.ORIENTATION_EXIF;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/interceptor/FileInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.datasource.interceptor;
20 |
21 | import android.graphics.BitmapRegionDecoder;
22 | import android.net.Uri;
23 | import android.util.Log;
24 |
25 | import java.io.File;
26 | import java.io.FileInputStream;
27 | import java.io.IOException;
28 |
29 | import xyz.zpayh.hdimage.BuildConfig;
30 | import xyz.zpayh.hdimage.datasource.Interceptor;
31 | import xyz.zpayh.hdimage.util.UriUtil;
32 |
33 | /**
34 | * 文 件 名: FileInterceptor
35 | * 创 建 人: 陈志鹏
36 | * 创建日期: 2017/7/29 17:49
37 | * 邮 箱: ch_zh_p@qq.com
38 | * 修改时间:
39 | * 修改备注:
40 | */
41 |
42 | public class FileInterceptor implements Interceptor {
43 |
44 | @Override
45 | public BitmapRegionDecoder intercept(Chain chain) throws IOException {
46 | final Uri uri = chain.uri();
47 | BitmapRegionDecoder decoder = chain.chain(uri);
48 | if (decoder != null){
49 | return decoder;
50 | }
51 |
52 |
53 | if (UriUtil.isLocalFileUri(uri)){
54 | File file = new File(uri.getPath());
55 | if (BuildConfig.DEBUG) {
56 | Log.d("FileInterceptor", "从我这加载");
57 | }
58 | try {
59 | return BitmapRegionDecoder.newInstance(new FileInputStream(file.toString()),false);
60 | } catch (IOException e) {
61 | return Interceptors.fixJPEGDecoder(file,e);
62 | }
63 | }
64 | return null;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/interceptor/FileOrientationInterceptor.java:
--------------------------------------------------------------------------------
1 | package xyz.zpayh.hdimage.datasource.interceptor;
2 |
3 | import android.content.Context;
4 | import androidx.annotation.NonNull;
5 | import androidx.exifinterface.media.ExifInterface;
6 |
7 | import java.io.IOException;
8 |
9 | import xyz.zpayh.hdimage.datasource.OrientationInterceptor;
10 | import xyz.zpayh.hdimage.state.Orientation;
11 |
12 | import static xyz.zpayh.hdimage.datasource.BitmapDataSource.FILE_SCHEME;
13 |
14 | public class FileOrientationInterceptor implements OrientationInterceptor {
15 | @Override
16 | public int getExifOrientation(@NonNull Context context, String sourceUri) {
17 | if (sourceUri.startsWith(FILE_SCHEME)) {
18 | try {
19 | String fileName = sourceUri.substring(FILE_SCHEME.length());
20 | ExifInterface exifInterface = new ExifInterface(fileName);
21 | int orientationAttr = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);
22 | switch (orientationAttr) {
23 | case ExifInterface.ORIENTATION_NORMAL:
24 | case ExifInterface.ORIENTATION_UNDEFINED:
25 | return Orientation.ORIENTATION_0;
26 | case ExifInterface.ORIENTATION_ROTATE_90:
27 | return Orientation.ORIENTATION_90;
28 | case ExifInterface.ORIENTATION_ROTATE_180:
29 | return Orientation.ORIENTATION_180;
30 | case ExifInterface.ORIENTATION_ROTATE_270:
31 | return Orientation.ORIENTATION_270;
32 | }
33 | } catch (IOException e) {
34 | e.printStackTrace();
35 | }
36 | }
37 | return Orientation.ORIENTATION_EXIF;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/interceptor/Interceptors.java:
--------------------------------------------------------------------------------
1 | package xyz.zpayh.hdimage.datasource.interceptor;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.BitmapRegionDecoder;
7 | import android.net.Uri;
8 | import androidx.annotation.NonNull;
9 | import androidx.exifinterface.media.ExifInterface;
10 | import android.util.Log;
11 |
12 | import java.io.BufferedInputStream;
13 | import java.io.BufferedOutputStream;
14 | import java.io.ByteArrayOutputStream;
15 | import java.io.File;
16 | import java.io.FileInputStream;
17 | import java.io.IOException;
18 | import java.io.InputStream;
19 | import java.io.OutputStream;
20 |
21 | import xyz.zpayh.hdimage.BuildConfig;
22 | import xyz.zpayh.hdimage.state.Orientation;
23 | import xyz.zpayh.hdimage.util.DiskLruCache;
24 | import xyz.zpayh.hdimage.util.ImageCache;
25 | import xyz.zpayh.hdimage.util.Preconditions;
26 | import xyz.zpayh.hdimage.util.UriUtil;
27 |
28 | /**
29 | * 创建人: zp
30 | * 创建时间:2017/8/3
31 | */
32 |
33 | public class Interceptors {
34 |
35 | private static final String TAG = "Interceptors";
36 |
37 | private static final int FIX_CACHE_SIZE = 10 * 1024 * 1024; // 20MB
38 | private static final String FIX_CACHE_DIR = "fixJPEG";
39 | private static final int IO_BUFFER_SIZE = 8 * 1024;
40 |
41 | private static final int DISK_CACHE_INDEX = 0;
42 |
43 | private static DiskLruCache mHttpDiskCache;
44 |
45 | public static void initDiskLruCache(Context context){
46 | if (mHttpDiskCache != null){
47 | return;
48 | }
49 | Preconditions.checkNotNull(context);
50 | File httpCacheDir = ImageCache.getDiskCacheDir(context, FIX_CACHE_DIR);
51 | if (!httpCacheDir.exists()){
52 | if (!httpCacheDir.mkdirs()){
53 | mHttpDiskCache = null;
54 | return;
55 | }
56 | }
57 | if (ImageCache.getUsableSpace(httpCacheDir) > FIX_CACHE_SIZE){
58 | try {
59 | mHttpDiskCache = DiskLruCache.open(httpCacheDir,1,1, FIX_CACHE_SIZE);
60 | } catch (IOException e) {
61 | e.printStackTrace();
62 | mHttpDiskCache = null;
63 | }
64 | }
65 | }
66 |
67 | private static synchronized File processFile(InputStream data, String url, IOException e) throws IOException{
68 | if (BuildConfig.DEBUG) {
69 | Log.d(TAG, "processFile - " + data);
70 | }
71 | final String key = ImageCache.hashKeyForDisk(url);
72 | DiskLruCache.Snapshot snapshot;
73 |
74 | File file = null;
75 |
76 | if (mHttpDiskCache != null) {
77 | snapshot = mHttpDiskCache.get(key);
78 | if (snapshot == null) {
79 | if (BuildConfig.DEBUG) {
80 | Log.d(TAG, "processBitmap, not found in http cache, downloading...");
81 | }
82 | DiskLruCache.Editor editor = mHttpDiskCache.edit(key);
83 | if (editor != null) {
84 | if (downloadUrlToStream(data,
85 | editor.newOutputStream(DISK_CACHE_INDEX))) {
86 | editor.commit();
87 | } else {
88 | editor.abort();
89 | }
90 | }
91 | mHttpDiskCache.flush();
92 | snapshot = mHttpDiskCache.get(key);
93 | }
94 | if (snapshot != null) {
95 | file = new File(mHttpDiskCache.getDirectory(), key + "." + DISK_CACHE_INDEX);
96 | }
97 | }
98 |
99 | if (file == null || !file.exists()){
100 | if (BuildConfig.DEBUG) {
101 | Log.d(TAG, "下载缓存失败:" + url);
102 | }
103 | throw e;
104 | }
105 |
106 | return file;
107 | }
108 |
109 | private static boolean downloadUrlToStream(InputStream inputStream, OutputStream outputStream) throws IOException{
110 |
111 | BufferedInputStream in = new BufferedInputStream(inputStream, IO_BUFFER_SIZE);
112 | BufferedOutputStream out = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE);
113 |
114 | int b;
115 | while ((b = in.read()) != -1) {
116 | out.write(b);
117 | }
118 | try {
119 | out.close();
120 | in.close();
121 | } catch (final IOException e) {e.printStackTrace();}
122 |
123 | return true;
124 | }
125 |
126 | public static BitmapRegionDecoder fixJPEGDecoder(InputStream inputStream, Uri uri, IOException e) throws IOException {
127 | return fixJPEGDecoder(processFile(inputStream,uri.toString(),e),e);
128 | }
129 |
130 | public static BitmapRegionDecoder fixJPEGDecoder(File file, IOException e) throws IOException {
131 |
132 | if (file == null || !file.exists()){
133 | throw e;
134 | }
135 |
136 | Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(),new BitmapFactory.Options());
137 | if (bitmap == null) {
138 | if (BuildConfig.DEBUG) {
139 | Log.d(TAG, "加载缓存失败:" + file.getAbsolutePath());
140 | }
141 | throw e;
142 | }
143 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
144 | bitmap.compress(Bitmap.CompressFormat.WEBP, 85, baos);
145 | BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(baos.toByteArray(),0,baos.size(),false);
146 | bitmap.recycle();
147 | if (BuildConfig.DEBUG) {
148 | Log.d(TAG, "fixJPEGDecoder: 从此处修复Bitmap");
149 | }
150 | return decoder;
151 | }
152 |
153 | static int getExifOrientation(String sourceUri) {
154 | if (UriUtil.isNetworkUri(Uri.parse(sourceUri))) {
155 | try {
156 | final String key = ImageCache.hashKeyForDisk(sourceUri);
157 | if (mHttpDiskCache != null) {
158 | DiskLruCache.Snapshot snapshot = mHttpDiskCache.get(key);
159 | if (snapshot != null) {
160 | File file = new File(mHttpDiskCache.getDirectory(), key + "." + DISK_CACHE_INDEX);
161 | ExifInterface exifInterface = new ExifInterface(new FileInputStream(file));
162 | int orientationAttr = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);
163 | switch (orientationAttr) {
164 | case ExifInterface.ORIENTATION_NORMAL:
165 | case ExifInterface.ORIENTATION_UNDEFINED:
166 | return Orientation.ORIENTATION_0;
167 | case ExifInterface.ORIENTATION_ROTATE_90:
168 | return Orientation.ORIENTATION_90;
169 | case ExifInterface.ORIENTATION_ROTATE_180:
170 | return Orientation.ORIENTATION_180;
171 | case ExifInterface.ORIENTATION_ROTATE_270:
172 | return Orientation.ORIENTATION_270;
173 | }
174 | }
175 | }
176 | } catch (IOException e) {
177 | e.printStackTrace();
178 | }
179 | }
180 | return Orientation.ORIENTATION_EXIF;
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/interceptor/NetworkInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.datasource.interceptor;
20 |
21 | import android.content.Context;
22 | import android.graphics.BitmapRegionDecoder;
23 | import android.net.Uri;
24 | import androidx.annotation.CheckResult;
25 | import android.util.Log;
26 |
27 | import java.io.BufferedInputStream;
28 | import java.io.BufferedOutputStream;
29 | import java.io.File;
30 | import java.io.FileInputStream;
31 | import java.io.IOException;
32 | import java.io.OutputStream;
33 | import java.net.HttpURLConnection;
34 | import java.net.URL;
35 |
36 | import xyz.zpayh.hdimage.BuildConfig;
37 | import xyz.zpayh.hdimage.datasource.Interceptor;
38 | import xyz.zpayh.hdimage.util.DiskLruCache;
39 | import xyz.zpayh.hdimage.util.ImageCache;
40 | import xyz.zpayh.hdimage.util.Preconditions;
41 | import xyz.zpayh.hdimage.util.UriUtil;
42 |
43 | /**
44 | * 文 件 名: NetworkInterceptor
45 | * 创 建 人: 陈志鹏
46 | * 创建日期: 2017/7/30 01:37
47 | * 邮 箱: ch_zh_p@qq.com
48 | * 修改时间:
49 | * 修改备注:
50 | */
51 |
52 | public class NetworkInterceptor implements Interceptor{
53 | private static final String TAG = "NetworkInterceptor";
54 |
55 | private static final int HTTP_CACHE_SIZE = 20 * 1024 * 1024; // 20MB
56 | private static final String HTTP_CACHE_DIR = "http";
57 | private static final int IO_BUFFER_SIZE = 8 * 1024;
58 |
59 | private static final int DISK_CACHE_INDEX = 0;
60 |
61 | private DiskLruCache mHttpDiskCache;
62 |
63 | public NetworkInterceptor(Context context) {
64 | Preconditions.checkNotNull(context);
65 | initDiskLruCache(context);
66 | }
67 |
68 | private void initDiskLruCache(Context context){
69 | File httpCacheDir = ImageCache.getDiskCacheDir(context,HTTP_CACHE_DIR);
70 | if (!httpCacheDir.exists()){
71 | if (!httpCacheDir.mkdirs()){
72 | mHttpDiskCache = null;
73 | return;
74 | }
75 | }
76 | if (ImageCache.getUsableSpace(httpCacheDir) > HTTP_CACHE_SIZE){
77 | try {
78 | mHttpDiskCache = DiskLruCache.open(httpCacheDir,1,1,HTTP_CACHE_SIZE);
79 | } catch (IOException e) {
80 | e.printStackTrace();
81 | mHttpDiskCache = null;
82 | }
83 | }
84 | }
85 |
86 | @Override
87 | public BitmapRegionDecoder intercept(Chain chain) throws IOException {
88 | final Uri uri = chain.uri();
89 | BitmapRegionDecoder decoder = chain.chain(uri);
90 | if (decoder != null){
91 | return decoder;
92 | }
93 |
94 | if (UriUtil.isNetworkUri(uri)){
95 | if (BuildConfig.DEBUG) {
96 | Log.d("NetworkInterceptor", "从我这加载");
97 | }
98 | File file = processFile(uri.toString());
99 | if (file == null) {
100 | return null;
101 | }
102 | try {
103 | //InputStream inputStream = processBitmap(uri.toString());
104 | return BitmapRegionDecoder.newInstance(new FileInputStream(file),false);
105 | } catch (IOException e) {
106 | //e.printStackTrace();
107 | return Interceptors.fixJPEGDecoder(file,e);
108 | }
109 | }
110 | return null;
111 | }
112 |
113 | @CheckResult
114 | private synchronized File processFile(String data) throws IOException{
115 | if (BuildConfig.DEBUG) {
116 | Log.d(TAG, "processFile - " + data);
117 | }
118 |
119 | final String key = ImageCache.hashKeyForDisk(data);
120 | DiskLruCache.Snapshot snapshot;
121 |
122 | File file = null;
123 |
124 | if (mHttpDiskCache != null) {
125 | snapshot = mHttpDiskCache.get(key);
126 | if (snapshot == null) {
127 | if (BuildConfig.DEBUG) {
128 | Log.d(TAG, "processBitmap, not found in http cache, downloading...");
129 | }
130 | DiskLruCache.Editor editor = mHttpDiskCache.edit(key);
131 | if (editor != null) {
132 | if (downloadUrlToStream(data,
133 | editor.newOutputStream(DISK_CACHE_INDEX))) {
134 | editor.commit();
135 | } else {
136 | editor.abort();
137 | }
138 | }
139 | mHttpDiskCache.flush();
140 | snapshot = mHttpDiskCache.get(key);
141 | }
142 | if (snapshot != null) {
143 | file = new File(mHttpDiskCache.getDirectory(), key + "." + DISK_CACHE_INDEX);
144 | }
145 | }
146 |
147 | return file;
148 | }
149 |
150 | /**
151 | * Download a bitmap from a URL and write the content to an output stream.
152 | *
153 | * @param urlString The URL to fetch
154 | * @return true if successful, false otherwise
155 | */
156 | private boolean downloadUrlToStream(String urlString, OutputStream outputStream) throws IOException{
157 | final URL url = new URL(urlString);
158 | HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
159 | BufferedInputStream in = new BufferedInputStream(urlConnection.getInputStream(), IO_BUFFER_SIZE);
160 | BufferedOutputStream out = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE);
161 |
162 | int b;
163 | while ((b = in.read()) != -1) {
164 | out.write(b);
165 | }
166 |
167 | urlConnection.disconnect();
168 |
169 | try {
170 | out.close();
171 | in.close();
172 | } catch (final IOException e) {
173 | if (BuildConfig.DEBUG) {
174 | e.printStackTrace();
175 | }
176 | }
177 |
178 | return true;
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/interceptor/NetworkOrientationInterceptor.java:
--------------------------------------------------------------------------------
1 | package xyz.zpayh.hdimage.datasource.interceptor;
2 |
3 | import android.content.Context;
4 | import androidx.annotation.NonNull;
5 |
6 | import xyz.zpayh.hdimage.datasource.OrientationInterceptor;
7 |
8 | public class NetworkOrientationInterceptor implements OrientationInterceptor {
9 | @Override
10 | public int getExifOrientation(@NonNull Context context, String sourceUri) {
11 | return Interceptors.getExifOrientation(sourceUri);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/datasource/interceptor/ResourceInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.datasource.interceptor;
20 |
21 | import android.content.res.Resources;
22 | import android.graphics.BitmapRegionDecoder;
23 | import android.net.Uri;
24 | import android.util.Log;
25 |
26 | import java.io.IOException;
27 | import java.io.InputStream;
28 |
29 | import xyz.zpayh.hdimage.BuildConfig;
30 | import xyz.zpayh.hdimage.datasource.Interceptor;
31 | import xyz.zpayh.hdimage.util.UriUtil;
32 |
33 | /**
34 | * 文 件 名: ResourceInterceptor
35 | * 创 建 人: 陈志鹏
36 | * 创建日期: 2017/7/29 17:55
37 | * 邮 箱: ch_zh_p@qq.com
38 | * 修改时间:
39 | * 修改备注:
40 | */
41 |
42 | public class ResourceInterceptor implements Interceptor {
43 |
44 | private final Resources mResources;
45 |
46 | public ResourceInterceptor(Resources resources) {
47 | mResources = resources;
48 | }
49 |
50 | @Override
51 | public BitmapRegionDecoder intercept(Chain chain) throws IOException {
52 | final Uri uri = chain.uri();
53 | BitmapRegionDecoder decoder = chain.chain(uri);
54 | if (decoder != null){
55 | return decoder;
56 | }
57 |
58 | if (UriUtil.isLocalResourceUri(uri)){
59 | if (BuildConfig.DEBUG) {
60 | Log.d("ResourceInterceptor", "从我这加载");
61 | }
62 | try {
63 | InputStream inputStream = mResources.openRawResource(getResourceId(uri));
64 | return BitmapRegionDecoder.newInstance(inputStream,false);
65 | } catch (IOException e) {
66 | InputStream inputStream = mResources.openRawResource(getResourceId(uri));
67 | return Interceptors.fixJPEGDecoder(inputStream,uri,e);
68 | }
69 | }
70 | return null;
71 | }
72 |
73 | private static int getResourceId(Uri uri) {
74 | return Integer.parseInt(uri.getPath().substring(1));
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/state/Orientation.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.state;
20 |
21 | import androidx.annotation.IntDef;
22 |
23 | import java.lang.annotation.Retention;
24 | import java.lang.annotation.RetentionPolicy;
25 |
26 | /**
27 | * 文 件 名: Orientation
28 | * 创 建 人: 陈志鹏
29 | * 创建日期: 2017/4/14 20:17
30 | * 邮 箱: ch_zh_p@qq.com
31 | * 修改时间:
32 | * 修改备注:
33 | */
34 | @Retention(RetentionPolicy.SOURCE)
35 | @IntDef({
36 | Orientation.ORIENTATION_EXIF,
37 | Orientation.ORIENTATION_0,
38 | Orientation.ORIENTATION_90,
39 | Orientation.ORIENTATION_180,
40 | Orientation.ORIENTATION_270})
41 | public @interface Orientation {
42 | int ORIENTATION_EXIF = -1;
43 | int ORIENTATION_0 = 0;
44 | int ORIENTATION_90 = 1;
45 | int ORIENTATION_180 = 2;
46 | int ORIENTATION_270 = 3;
47 | }
48 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/state/ScaleType.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.state;
20 |
21 | import androidx.annotation.IntDef;
22 |
23 | import java.lang.annotation.Retention;
24 | import java.lang.annotation.RetentionPolicy;
25 |
26 | /**
27 | * 文 件 名: ScaleType
28 | * 创 建 人: 陈志鹏
29 | * 创建日期: 2017/4/15 02:13
30 | * 邮 箱: ch_zh_p@qq.com
31 | * 修改时间:
32 | * 修改备注:
33 | */
34 | @Retention(RetentionPolicy.SOURCE)
35 | @IntDef({
36 | ScaleType.CENTER_INSIDE,
37 | ScaleType.CENTER_CROP,
38 | ScaleType.CUSTOM
39 | })
40 | public @interface ScaleType {
41 | /**
42 | * 缩放图像,使图像的两个维度均等于或小于视图的相应维度。 图像然后在视图中居中。 这是默认行为,最适合画廊。
43 | */
44 | int CENTER_INSIDE = 1;
45 | /**
46 | * 缩放图像均匀,使图像的两个尺寸都等于或大于视图的相应尺寸。 图像然后在视图中居中。
47 | */
48 | int CENTER_CROP = 2;
49 | /**
50 | * 缩放图像,使图像的两个维度均等于或小于maxScale,并等于或大于minScale。 图像然后在视图中居中。
51 | */
52 | int CUSTOM = 3;
53 | }
54 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/state/Translation.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.state;
20 |
21 | import androidx.annotation.IntDef;
22 |
23 | import java.lang.annotation.Retention;
24 | import java.lang.annotation.RetentionPolicy;
25 |
26 | /**
27 | * 文 件 名: Translation
28 | * 创 建 人: 陈志鹏
29 | * 创建日期: 2017/4/15 00:03
30 | * 邮 箱: ch_zh_p@qq.com
31 | * 修改时间:
32 | * 修改备注:
33 | */
34 | @Retention(RetentionPolicy.SOURCE)
35 | @IntDef({
36 | Translation.INSIDE,
37 | Translation.OUTSIDE,
38 | Translation.CENTER,
39 | Translation.COUSTOM
40 | })
41 | public @interface Translation {
42 | /**
43 | * 图像始终全部显示在控件范围内
44 | */
45 | int INSIDE = 1;
46 | /**
47 | * 允许图像刚好平移到不可见
48 | */
49 | int OUTSIDE = 2;
50 | /**
51 | * 允许图像被平移,直到角落到屏幕的中心,但不再进一步。 当您想要将图像上的任何位置平移到屏幕的正确中心时很有用。
52 | */
53 | int CENTER = 3;
54 |
55 | /**
56 | * 自定义范围
57 | */
58 | int COUSTOM = 4;
59 | }
60 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/state/Zoom.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.state;
20 |
21 | import androidx.annotation.IntDef;
22 |
23 | import java.lang.annotation.Retention;
24 | import java.lang.annotation.RetentionPolicy;
25 |
26 | /**
27 | * 文 件 名: Zoom
28 | * 创 建 人: 陈志鹏
29 | * 创建日期: 2017/4/15 00:18
30 | * 邮 箱: ch_zh_p@qq.com
31 | * 修改时间:
32 | * 修改备注:
33 | */
34 | @Retention(RetentionPolicy.SOURCE)
35 | @IntDef({
36 | Zoom.ZOOM_FOCUS_FIXED,
37 | Zoom.ZOOM_FOCUS_CENTER,
38 | Zoom.ZOOM_FOCUS_CENTER_IMMEDIATE
39 | })
40 | public @interface Zoom {
41 |
42 | /**
43 | * 在缩放动画过程中,保持拍摄在相同位置的图像的点,并在其周围缩放图像。
44 | */
45 | int ZOOM_FOCUS_FIXED = 1;
46 | /**
47 | * 在缩放动画过程中,将拍摄的图像点移动到屏幕中央。
48 | */
49 | int ZOOM_FOCUS_CENTER = 2;
50 | /**
51 | * 立即放大并立即对中心点进行动画处理。
52 | */
53 | int ZOOM_FOCUS_CENTER_IMMEDIATE = 3;
54 | }
55 |
--------------------------------------------------------------------------------
/library/src/main/java/xyz/zpayh/hdimage/util/Utils.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | package xyz.zpayh.hdimage.util;
17 |
18 | import android.content.ContentResolver;
19 | import android.content.Context;
20 | import android.content.res.AssetManager;
21 | import android.database.Cursor;
22 | import android.graphics.Rect;
23 | import android.net.Uri;
24 | import android.os.Build;
25 | import android.os.Build.VERSION_CODES;
26 | import android.provider.MediaStore;
27 | import androidx.annotation.NonNull;
28 | import androidx.exifinterface.media.ExifInterface;
29 | import android.util.Log;
30 |
31 | import java.io.IOException;
32 |
33 | import xyz.zpayh.hdimage.state.Orientation;
34 |
35 | import static android.os.Build.VERSION.SDK_INT;
36 | import static xyz.zpayh.hdimage.datasource.BitmapDataSource.ASSET_SCHEME;
37 | import static xyz.zpayh.hdimage.datasource.BitmapDataSource.FILE_SCHEME;
38 | import static xyz.zpayh.hdimage.state.Orientation.ORIENTATION_0;
39 | import static xyz.zpayh.hdimage.state.Orientation.ORIENTATION_180;
40 | import static xyz.zpayh.hdimage.state.Orientation.ORIENTATION_270;
41 | import static xyz.zpayh.hdimage.state.Orientation.ORIENTATION_90;
42 | import static xyz.zpayh.hdimage.state.Orientation.ORIENTATION_EXIF;
43 |
44 | /**
45 | * Class containing some static utility methods.
46 | */
47 | public class Utils {
48 | private static final String TAG = "Utils";
49 | private Utils() {}
50 |
51 | @Orientation
52 | public static int getExifOrientation(@NonNull Context context, String sourceUri){
53 | int exifOrientation = ORIENTATION_0;
54 | if (sourceUri.startsWith(ContentResolver.SCHEME_CONTENT)){
55 | final String[] columns = {MediaStore.Images.Media.ORIENTATION};
56 | final Cursor cursor = context.getContentResolver()
57 | .query(Uri.parse(sourceUri),columns,null,null,null);
58 | if (cursor != null){
59 | if (cursor.moveToFirst()){
60 | int orientation = cursor.getInt(0);
61 | if (orientation == ORIENTATION_0){
62 | exifOrientation = ORIENTATION_0;
63 | } else if (orientation == ORIENTATION_90){
64 | exifOrientation = ORIENTATION_90;
65 | } else if (orientation == ORIENTATION_180){
66 | exifOrientation = ORIENTATION_180;
67 | } else if (orientation == ORIENTATION_270){
68 | exifOrientation = ORIENTATION_270;
69 | } else{
70 | Log.w(TAG, "Unsupported orientation: " + orientation);
71 | }
72 | }
73 | cursor.close();
74 | }
75 | return exifOrientation;
76 | }
77 |
78 | if (sourceUri.startsWith(FILE_SCHEME)){
79 | try {
80 | ExifInterface exifInterface = new ExifInterface(sourceUri.substring(FILE_SCHEME.length()));
81 | int orientationAttr = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
82 | ExifInterface.ORIENTATION_NORMAL);
83 | if (orientationAttr == ExifInterface.ORIENTATION_NORMAL ||
84 | orientationAttr == ExifInterface.ORIENTATION_UNDEFINED){
85 | exifOrientation = ORIENTATION_0;
86 | }else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_90){
87 | exifOrientation = ORIENTATION_90;
88 | }else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_180){
89 | exifOrientation = ORIENTATION_180;
90 | }else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_270){
91 | exifOrientation = ORIENTATION_270;
92 | }else{
93 | Log.w(TAG, "Unsupported EXIF orientation: " + orientationAttr);
94 | }
95 | } catch (IOException e) {
96 | e.printStackTrace();
97 | Log.w(TAG, "Could not get EXIF orientation of image");
98 | }
99 |
100 | return exifOrientation;
101 | }
102 |
103 | if (sourceUri.startsWith(ASSET_SCHEME) && SDK_INT >= 24){
104 | try {
105 | String assetName = sourceUri.substring(ASSET_SCHEME.length());
106 | ExifInterface exifInterface = new ExifInterface(context.getAssets().open(assetName, AssetManager.ACCESS_RANDOM));
107 | int orientationAttr = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
108 | ExifInterface.ORIENTATION_NORMAL);
109 | if (orientationAttr == ExifInterface.ORIENTATION_NORMAL ||
110 | orientationAttr == ExifInterface.ORIENTATION_UNDEFINED){
111 | exifOrientation = ORIENTATION_0;
112 | }else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_90){
113 | exifOrientation = ORIENTATION_90;
114 | }else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_180){
115 | exifOrientation = ORIENTATION_180;
116 | }else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_270){
117 | exifOrientation = ORIENTATION_270;
118 | }else{
119 | Log.w(TAG, "Unsupported EXIF orientation: " + orientationAttr);
120 | }
121 | } catch (IOException e) {
122 | e.printStackTrace();
123 | }
124 | }
125 |
126 | return exifOrientation;
127 | }
128 |
129 | @SuppressWarnings("SuspiciousNameCombination")
130 | public static void fileRect(@NonNull Rect rect, @NonNull Rect target, int width,
131 | int height, int rotation){
132 | switch (rotation){
133 | case ORIENTATION_0:
134 | target.set(rect);
135 | return;
136 | case ORIENTATION_90:
137 | target.set(rect.top,height - rect.right,
138 | rect.bottom,height - rect.left);
139 | return;
140 | case ORIENTATION_180:
141 | target.set(width - rect.right, height - rect.bottom,
142 | width - rect.left, height - rect.top);
143 | return;
144 | case ORIENTATION_270:
145 | case ORIENTATION_EXIF:
146 | default:
147 | target.set(width-rect.bottom,rect.left,width-rect.top,
148 | rect.right);
149 | }
150 | }
151 |
152 | public static boolean hasHoneycombMR1() {
153 | return Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1;
154 | }
155 |
156 | public static boolean hasKitKat() {
157 | return Build.VERSION.SDK_INT >= VERSION_CODES.KITKAT;
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/library/src/main/res/values/attr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | HDImageView
3 |
4 |
--------------------------------------------------------------------------------
/library/src/test/java/xyz/zpayh/hdimage/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package xyz.zpayh.hdimage;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':library', ':support-fresco', ':support-glide'
2 |
--------------------------------------------------------------------------------
/support-fresco/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/support-fresco/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | apply plugin: 'com.android.library'
20 | //apply plugin: 'com.github.panpf.bintray-publish'
21 |
22 | android {
23 | compileSdkVersion 29
24 |
25 | defaultConfig {
26 | minSdkVersion 14
27 | targetSdkVersion 29
28 | versionCode 4
29 | versionName "3.0.0"
30 |
31 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
32 |
33 | }
34 | buildTypes {
35 | release {
36 | minifyEnabled false
37 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
38 | }
39 | }
40 | lintOptions{
41 | abortOnError false
42 | }
43 | }
44 |
45 | dependencies {
46 | implementation fileTree(include: ['*.jar'], dir: 'libs')
47 | androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
48 | exclude group: 'com.android.support', module: 'support-annotations'
49 | })
50 | implementation 'androidx.appcompat:appcompat:1.2.0'
51 | testImplementation 'junit:junit:4.13.2'
52 | compileOnly 'com.facebook.fresco:fresco:2.4.0'
53 | //compileOnly 'xyz.zpayh:hdimageview:3.0.2'
54 | implementation project(':library')
55 | }
56 |
57 | // jcenter configuration for novoda's bintray-release
58 | // $ ./gradlew clean build bintrayUpload -PbintrayUser=BINTRAY_USERNAME -PbintrayKey=BINTRAY_KEY -PdryRun=false
59 | /*publish {
60 | userOrg = 'sherlock' //bintray注册的用户名
61 | groupId = 'xyz.zpayh' //compile引用时的第1部分groupId
62 | artifactId = 'hdimageview-fresco' //compile引用时的第2部分项目名
63 | publishVersion = '3.0.0' //compile引用时的第3部分版本号
64 | desc = 'This is a high-definition picture control that supports zooming'
65 | website = 'https://github.com/EvilBT/HDImageView'
66 | }*/
67 |
--------------------------------------------------------------------------------
/support-fresco/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Keep our interfaces so they can be used by other ProGuard rules.
2 | # See http://sourceforge.net/p/proguard/bugs/466/
3 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
4 |
5 | # Do not strip any method/class that is annotated with @DoNotStrip
6 | -keep @com.facebook.common.internal.DoNotStrip class *
7 | -keepclassmembers class * {
8 | @com.facebook.common.internal.DoNotStrip *;
9 | }
10 |
11 | # Keep native methods
12 | -keepclassmembers class * {
13 | native ;
14 | }
15 |
16 | -dontwarn okio.**
17 | -dontwarn com.squareup.okhttp.**
18 | -dontwarn okhttp3.**
19 | -dontwarn javax.annotation.**
20 | -dontwarn com.android.volley.toolbox.**
21 | -dontwarn com.facebook.infer.**
22 |
--------------------------------------------------------------------------------
/support-fresco/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
21 |
22 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/support-fresco/src/main/java/xyz/zpayh/hdimage/datasource/interceptor/FrescoInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.datasource.interceptor;
20 |
21 | import android.graphics.BitmapRegionDecoder;
22 | import android.net.Uri;
23 | import android.util.Log;
24 |
25 | import com.facebook.binaryresource.BinaryResource;
26 | import com.facebook.binaryresource.FileBinaryResource;
27 | import com.facebook.cache.common.CacheKey;
28 | import com.facebook.common.internal.Closeables;
29 | import com.facebook.common.memory.PooledByteBuffer;
30 | import com.facebook.common.memory.PooledByteBufferInputStream;
31 | import com.facebook.common.references.CloseableReference;
32 | import com.facebook.common.util.UriUtil;
33 | import com.facebook.datasource.DataSource;
34 | import com.facebook.datasource.DataSources;
35 | import com.facebook.imagepipeline.cache.DefaultCacheKeyFactory;
36 | import com.facebook.imagepipeline.core.ImagePipeline;
37 | import com.facebook.imagepipeline.core.ImagePipelineFactory;
38 | import com.facebook.imagepipeline.request.ImageRequest;
39 |
40 | import java.io.File;
41 | import java.io.IOException;
42 | import java.io.InputStream;
43 |
44 | import xyz.zpayh.hdimage.datasource.Interceptor;
45 |
46 | /**
47 | * 文 件 名: FrescoInterceptor
48 | * 创 建 人: 陈志鹏
49 | * 创建日期: 2017/7/30 16:07
50 | * 邮 箱: ch_zh_p@qq.com
51 | * 修改时间:
52 | * 修改备注: 只加载网络图片
53 | */
54 |
55 | public class FrescoInterceptor implements Interceptor {
56 | @Override
57 | public BitmapRegionDecoder intercept(Chain chain) throws IOException {
58 | final Uri uri = chain.uri();
59 | BitmapRegionDecoder decoder = chain.chain(uri);
60 | if (decoder != null){
61 | return decoder;
62 | }
63 |
64 | if (UriUtil.isNetworkUri(uri)){
65 | ImagePipeline imagePipeline = ImagePipelineFactory.getInstance().getImagePipeline();
66 |
67 | ImageRequest request = ImageRequest.fromUri(uri);
68 | DataSource> dataSource = imagePipeline.fetchEncodedImage(request,null);
69 | try {
70 | CloseableReference ref = DataSources.waitForFinalResult(dataSource);
71 | if (ref == null){
72 | return null;
73 | }
74 | PooledByteBuffer result = ref.get();
75 | if (BuildConfig.DEBUG) {
76 | Log.d("FrescoInterceptor", "从我这加载");
77 | }
78 | try {
79 | InputStream inputStream = new PooledByteBufferInputStream(result);
80 | Closeables.closeQuietly(inputStream);
81 | return BitmapRegionDecoder.newInstance(inputStream,false);
82 | } catch (IOException e) {
83 | ImageRequest imageRequest=ImageRequest.fromUri(uri);
84 | CacheKey cacheKey= DefaultCacheKeyFactory.getInstance().getEncodedCacheKey(imageRequest,null);
85 | BinaryResource resource = ImagePipelineFactory.getInstance().getMainFileCache().getResource(cacheKey);
86 | File file=((FileBinaryResource)resource).getFile();
87 | if (BuildConfig.DEBUG) {
88 | Log.d("FrescoInterceptor", file.getName());
89 | }
90 | return Interceptors.fixJPEGDecoder(file,e);
91 | }
92 | } catch (Throwable throwable) {
93 | if (BuildConfig.DEBUG) {
94 | Log.d("FrescoInterceptor", "intercept: 加载失败了");
95 | }
96 | throwable.printStackTrace();
97 | return null;
98 | }
99 | }
100 |
101 | return null;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/support-glide/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/support-glide/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | apply plugin: 'com.android.library'
20 | //apply plugin: 'com.github.panpf.bintray-publish'
21 |
22 | android {
23 | compileSdkVersion 28
24 |
25 | defaultConfig {
26 | minSdkVersion 14
27 | targetSdkVersion 28
28 | versionCode 4
29 | versionName "3.0.0"
30 |
31 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
32 |
33 | }
34 | buildTypes {
35 | release {
36 | minifyEnabled false
37 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
38 | }
39 | }
40 | lintOptions{
41 | abortOnError false
42 | }
43 | }
44 |
45 | dependencies {
46 | implementation fileTree(include: ['*.jar'], dir: 'libs')
47 | androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
48 | exclude group: 'com.android.support', module: 'support-annotations'
49 | })
50 | implementation 'androidx.appcompat:appcompat:1.2.0'
51 | testImplementation 'junit:junit:4.13.2'
52 | //compileOnly 'xyz.zpayh:hdimageview:3.0.2'
53 | implementation project(':library')
54 | compileOnly 'com.github.bumptech.glide:glide:4.12.0'
55 | }
56 |
57 | // jcenter configuration for novoda's bintray-release
58 | // $ ./gradlew clean build bintrayUpload -PbintrayUser=BINTRAY_USERNAME -PbintrayKey=BINTRAY_KEY -PdryRun=false
59 | /*publish {
60 | userOrg = 'sherlock' //bintray注册的用户名
61 | groupId = 'xyz.zpayh' //compile引用时的第1部分groupId
62 | artifactId = 'hdimageview-glide' //compile引用时的第2部分项目名
63 | publishVersion = '3.0.0' //compile引用时的第3部分版本号
64 | desc = 'This is a high-definition picture control that supports zooming'
65 | website = 'https://github.com/EvilBT/HDImageView'
66 | }*/
67 |
--------------------------------------------------------------------------------
/support-glide/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in H:\android-sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/support-glide/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/support-glide/src/main/java/xyz/zpayh/hdimage/datasource/interceptor/GlideInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * Copyright 2017 陈志鹏
4 | * *
5 | * * Licensed under the Apache License, Version 2.0 (the "License");
6 | * * you may not use this file except in compliance with the License.
7 | * * You may obtain a copy of the License at
8 | * *
9 | * * http://www.apache.org/licenses/LICENSE-2.0
10 | * *
11 | * * Unless required by applicable law or agreed to in writing, software
12 | * * distributed under the License is distributed on an "AS IS" BASIS,
13 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * * See the License for the specific language governing permissions and
15 | * * limitations under the License.
16 | *
17 | */
18 |
19 | package xyz.zpayh.hdimage.datasource.interceptor;
20 |
21 | import android.content.Context;
22 | import android.graphics.BitmapRegionDecoder;
23 | import android.net.Uri;
24 | import android.util.Log;
25 |
26 | import com.bumptech.glide.Glide;
27 | import com.bumptech.glide.RequestManager;
28 | import com.bumptech.glide.request.FutureTarget;
29 |
30 | import java.io.File;
31 | import java.io.FileInputStream;
32 | import java.io.IOException;
33 | import java.util.concurrent.ExecutionException;
34 |
35 | import xyz.zpayh.hdimage.datasource.BuildConfig;
36 | import xyz.zpayh.hdimage.datasource.Interceptor;
37 | import xyz.zpayh.hdimage.util.Preconditions;
38 | import xyz.zpayh.hdimage.util.UriUtil;
39 |
40 | /**
41 | * 文 件 名: GlideInterceptor
42 | * 创 建 人: 陈志鹏
43 | * 创建日期: 2017/7/30 17:48
44 | * 邮 箱: ch_zh_p@qq.com
45 | * 修改时间:
46 | * 修改备注: 只加载网络图片
47 | */
48 |
49 | public class GlideInterceptor implements Interceptor{
50 |
51 | private final RequestManager mRequestManager;
52 |
53 | public GlideInterceptor(Context context) {
54 | Preconditions.checkNotNull(context);
55 |
56 | mRequestManager = Glide.with(context);
57 | }
58 |
59 | @Override
60 | public BitmapRegionDecoder intercept(Chain chain) throws IOException {
61 | final Uri uri = chain.uri();
62 | BitmapRegionDecoder decoder = chain.chain(uri);
63 | if (decoder != null){
64 | return decoder;
65 | }
66 |
67 | if (UriUtil.isNetworkUri(uri)){
68 | FutureTarget target = mRequestManager.downloadOnly().load(uri).submit();
69 | try {
70 | File file = target.get();
71 | if (BuildConfig.DEBUG) {
72 | Log.d("GlideInterceptor", "用GlideInterceptor加载回来" + file.getAbsolutePath());
73 | }
74 | try {
75 | decoder = BitmapRegionDecoder.newInstance(new FileInputStream(file),false);
76 | } catch (IOException e) {
77 | return Interceptors.fixJPEGDecoder(file,e);
78 | }
79 | } catch (InterruptedException e) {
80 | e.printStackTrace();
81 | } catch (ExecutionException e) {
82 | e.printStackTrace();
83 | }
84 | mRequestManager.clear(target);
85 | }
86 | return decoder;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------