/
ImageAssetManager.java
138 lines (122 loc) · 4.27 KB
/
ImageAssetManager.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package com.airbnb.lottie.manager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import androidx.annotation.Nullable;
import android.text.TextUtils;
import android.util.Base64;
import android.view.View;
import com.airbnb.lottie.ImageAssetDelegate;
import com.airbnb.lottie.LottieImageAsset;
import com.airbnb.lottie.utils.Logger;
import com.airbnb.lottie.utils.Utils;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
public class ImageAssetManager {
private static final Object bitmapHashLock = new Object();
private final Context context;
private final String imagesFolder;
@Nullable private ImageAssetDelegate delegate;
private final Map<String, LottieImageAsset> imageAssets;
public ImageAssetManager(Drawable.Callback callback, String imagesFolder,
ImageAssetDelegate delegate, Map<String, LottieImageAsset> imageAssets) {
if (!TextUtils.isEmpty(imagesFolder) && imagesFolder.charAt(imagesFolder.length() - 1) != '/') {
this.imagesFolder = imagesFolder + '/';
} else {
this.imagesFolder = imagesFolder;
}
if (!(callback instanceof View)) {
Logger.warning("LottieDrawable must be inside of a view for images to work.");
this.imageAssets = new HashMap<>();
context = null;
return;
}
context = ((View) callback).getContext();
this.imageAssets = imageAssets;
setDelegate(delegate);
}
public void setDelegate(@Nullable ImageAssetDelegate assetDelegate) {
this.delegate = assetDelegate;
}
/**
* Returns the previously set bitmap or null.
*/
@Nullable public Bitmap updateBitmap(String id, @Nullable Bitmap bitmap) {
if (bitmap == null) {
LottieImageAsset asset = imageAssets.get(id);
Bitmap ret = asset.getBitmap();
asset.setBitmap(null);
return ret;
}
Bitmap prevBitmap = imageAssets.get(id).getBitmap();
putBitmap(id, bitmap);
return prevBitmap;
}
@Nullable public LottieImageAsset getImageAssetById(String id) {
return imageAssets.get(id);
}
@Nullable public Bitmap bitmapForId(String id) {
LottieImageAsset asset = imageAssets.get(id);
if (asset == null) {
return null;
}
Bitmap bitmap = asset.getBitmap();
if (bitmap != null) {
return bitmap;
}
if (delegate != null) {
bitmap = delegate.fetchBitmap(asset);
if (bitmap != null) {
putBitmap(id, bitmap);
}
return bitmap;
}
String filename = asset.getFileName();
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inScaled = true;
opts.inDensity = 160;
if (filename.startsWith("data:") && filename.indexOf("base64,") > 0) {
// Contents look like a base64 data URI, with the format data:image/png;base64,<data>.
byte[] data;
try {
data = Base64.decode(filename.substring(filename.indexOf(',') + 1), Base64.DEFAULT);
} catch (IllegalArgumentException e) {
Logger.warning("data URL did not have correct base64 format.", e);
return null;
}
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opts);
return putBitmap(id, bitmap);
}
InputStream is;
try {
if (TextUtils.isEmpty(imagesFolder)) {
throw new IllegalStateException("You must set an images folder before loading an image." +
" Set it with LottieComposition#setImagesFolder or LottieDrawable#setImagesFolder");
}
is = context.getAssets().open(imagesFolder + filename);
} catch (IOException e) {
Logger.warning("Unable to open asset.", e);
return null;
}
try {
bitmap = BitmapFactory.decodeStream(is, null, opts);
} catch (IllegalArgumentException e) {
Logger.warning("Unable to decode image.", e);
return null;
}
bitmap = Utils.resizeBitmapIfNeeded(bitmap, asset.getWidth(), asset.getHeight());
return putBitmap(id, bitmap);
}
public boolean hasSameContext(Context context) {
return context == null && this.context == null || this.context.equals(context);
}
private Bitmap putBitmap(String key, @Nullable Bitmap bitmap) {
synchronized (bitmapHashLock) {
imageAssets.get(key).setBitmap(bitmap);
return bitmap;
}
}
}