NekoX/TMessagesProj/src/main/java/org/telegram/android/ImageReceiver.java

380 lines
13 KiB
Java
Raw Normal View History

/*
* This is the source code of Telegram for Android v. 1.3.x.
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Nikolai Kudashov, 2013.
*/
package org.telegram.android;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.View;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.Utilities;
public class ImageReceiver {
private TLRPC.FileLocation last_path = null;
private String last_httpUrl = null;
private String last_filter = null;
private Drawable last_placeholder = null;
private int last_size = 0;
private String currentPath = null;
private boolean isPlaceholder = false;
private Drawable currentImage = null;
private Integer tag = null;
private View parentView = null;
private int imageX = 0, imageY = 0, imageW = 0, imageH = 0;
private Rect drawRegion = new Rect();
private boolean isVisible = true;
private boolean isAspectFit = false;
2014-10-07 22:14:27 +02:00
private boolean lastCacheOnly = false;
private boolean forcePreview = false;
public ImageReceiver() {
}
public ImageReceiver(View view) {
parentView = view;
}
2014-10-07 22:14:27 +02:00
public void setImage(TLRPC.FileLocation path, String filter, Drawable placeholder, boolean cacheOnly) {
setImage(path, null, filter, placeholder, 0, cacheOnly);
}
2014-10-07 22:14:27 +02:00
public void setImage(TLRPC.FileLocation path, String filter, Drawable placeholder, int size, boolean cacheOnly) {
setImage(path, null, filter, placeholder, size, cacheOnly);
}
public void setImage(String path, String filter, Drawable placeholder) {
2014-10-07 22:14:27 +02:00
setImage(null, path, filter, placeholder, 0, true);
}
2014-10-07 22:14:27 +02:00
public void setImage(TLRPC.FileLocation fileLocation, String httpUrl, String filter, Drawable placeholder, int size, boolean cacheOnly) {
if ((fileLocation == null && httpUrl == null) || (fileLocation != null && !(fileLocation instanceof TLRPC.TL_fileLocation) && !(fileLocation instanceof TLRPC.TL_fileEncryptedLocation))) {
recycleBitmap(null);
currentPath = null;
isPlaceholder = true;
last_path = null;
last_httpUrl = null;
last_filter = null;
2014-10-07 22:14:27 +02:00
lastCacheOnly = false;
last_placeholder = placeholder;
last_size = 0;
currentImage = null;
ImageLoader.getInstance().cancelLoadingForImageView(this);
if (parentView != null) {
parentView.invalidate();
}
return;
}
String key;
if (fileLocation != null) {
key = fileLocation.volume_id + "_" + fileLocation.local_id;
} else {
key = Utilities.MD5(httpUrl);
}
if (filter != null) {
key += "@" + filter;
}
BitmapDrawable img = null;
if (currentPath != null) {
if (currentPath.equals(key)) {
if (currentImage != null) {
return;
} else {
img = ImageLoader.getInstance().getImageFromMemory(fileLocation, httpUrl, filter, this);
}
} else {
img = ImageLoader.getInstance().getImageFromMemory(fileLocation, httpUrl, filter, this);
recycleBitmap(img);
}
}
img = ImageLoader.getInstance().getImageFromMemory(fileLocation, httpUrl, filter, this);
currentPath = key;
last_path = fileLocation;
last_httpUrl = httpUrl;
last_filter = filter;
last_placeholder = placeholder;
last_size = size;
2014-10-07 22:14:27 +02:00
lastCacheOnly = cacheOnly;
if (img == null) {
isPlaceholder = true;
2014-10-07 22:14:27 +02:00
ImageLoader.getInstance().loadImage(fileLocation, httpUrl, this, size, cacheOnly);
} else {
setImageBitmap(img, currentPath);
}
}
public void setImageBitmap(BitmapDrawable bitmap, String imgKey) {
if (currentPath == null || !imgKey.equals(currentPath)) {
return;
}
isPlaceholder = false;
ImageLoader.getInstance().incrementUseCount(currentPath);
currentImage = bitmap;
2014-08-29 23:06:04 +02:00
if (parentView != null) {
2014-06-12 21:55:13 +02:00
parentView.invalidate();
}
}
public void setImageBitmap(Bitmap bitmap) {
ImageLoader.getInstance().cancelLoadingForImageView(this);
recycleBitmap(null);
if (bitmap != null) {
last_placeholder = new BitmapDrawable(null, bitmap);
} else {
last_placeholder = null;
}
isPlaceholder = true;
currentPath = null;
last_path = null;
last_httpUrl = null;
last_filter = null;
currentImage = null;
last_size = 0;
2014-10-07 22:14:27 +02:00
lastCacheOnly = false;
if (parentView != null) {
parentView.invalidate();
}
}
public void setImageBitmap(Drawable bitmap) {
ImageLoader.getInstance().cancelLoadingForImageView(this);
recycleBitmap(null);
last_placeholder = bitmap;
isPlaceholder = true;
currentPath = null;
currentImage = null;
last_path = null;
last_httpUrl = null;
last_filter = null;
last_size = 0;
2014-10-07 22:14:27 +02:00
lastCacheOnly = false;
if (parentView != null) {
parentView.invalidate();
}
}
public void clearImage() {
recycleBitmap(null);
}
private void recycleBitmap(BitmapDrawable newBitmap) {
if (currentImage == null || isPlaceholder) {
return;
}
if (currentImage instanceof BitmapDrawable) {
if (currentImage != newBitmap) {
if (currentPath != null) {
Bitmap bitmap = ((BitmapDrawable) currentImage).getBitmap();
boolean canDelete = ImageLoader.getInstance().decrementUseCount(currentPath);
if (!ImageLoader.getInstance().isInCache(currentPath)) {
if (ImageLoader.getInstance().runtimeHack != null) {
ImageLoader.getInstance().runtimeHack.trackAlloc(bitmap.getRowBytes() * bitmap.getHeight());
}
if (canDelete) {
currentImage = null;
bitmap.recycle();
}
} else {
currentImage = null;
}
2014-03-27 15:25:53 +01:00
currentPath = null;
}
}
}
}
2014-08-29 23:06:04 +02:00
public boolean draw(Canvas canvas, int x, int y, int w, int h) {
try {
Drawable bitmapDrawable = currentImage;
if (forcePreview || bitmapDrawable == null && last_placeholder != null && last_placeholder instanceof BitmapDrawable) {
bitmapDrawable = last_placeholder;
}
if (bitmapDrawable != null) {
int bitmapW = bitmapDrawable.getIntrinsicWidth();
int bitmapH = bitmapDrawable.getIntrinsicHeight();
float scaleW = bitmapW / (float)w;
float scaleH = bitmapH / (float)h;
2014-07-10 02:15:58 +02:00
if (isAspectFit) {
float scale = Math.max(scaleW, scaleH);
canvas.save();
2014-07-10 02:15:58 +02:00
bitmapW /= scale;
bitmapH /= scale;
drawRegion.set(x + (w - bitmapW) / 2, y + (h - bitmapH) / 2, x + (w + bitmapW) / 2, y + (h + bitmapH) / 2);
bitmapDrawable.setBounds(drawRegion);
2014-10-01 21:55:24 +02:00
try {
bitmapDrawable.draw(canvas);
} catch (Exception e) {
if (currentPath != null) {
ImageLoader.getInstance().removeImage(currentPath);
currentPath = null;
}
2014-10-07 22:14:27 +02:00
setImage(last_path, last_httpUrl, last_filter, last_placeholder, last_size, lastCacheOnly);
2014-10-01 21:55:24 +02:00
FileLog.e("tmessages", e);
}
canvas.restore();
} else {
2014-07-10 02:15:58 +02:00
if (Math.abs(scaleW - scaleH) > 0.00001f) {
canvas.save();
canvas.clipRect(x, y, x + w, y + h);
if (bitmapW / scaleH > w) {
bitmapW /= scaleH;
drawRegion.set(x - (bitmapW - w) / 2, y, x + (bitmapW + w) / 2, y + h);
} else {
bitmapH /= scaleW;
drawRegion.set(x, y - (bitmapH - h) / 2, x + w, y + (bitmapH + h) / 2);
}
bitmapDrawable.setBounds(drawRegion);
if (isVisible) {
2014-10-01 21:55:24 +02:00
try {
bitmapDrawable.draw(canvas);
} catch (Exception e) {
if (currentPath != null) {
ImageLoader.getInstance().removeImage(currentPath);
currentPath = null;
}
2014-10-07 22:14:27 +02:00
setImage(last_path, last_httpUrl, last_filter, last_placeholder, last_size, lastCacheOnly);
2014-10-01 21:55:24 +02:00
FileLog.e("tmessages", e);
}
2014-07-10 02:15:58 +02:00
}
canvas.restore();
} else {
drawRegion.set(x, y, x + w, y + h);
bitmapDrawable.setBounds(drawRegion);
if (isVisible) {
2014-10-01 21:55:24 +02:00
try {
bitmapDrawable.draw(canvas);
} catch (Exception e) {
if (currentPath != null) {
ImageLoader.getInstance().removeImage(currentPath);
currentPath = null;
}
2014-10-07 22:14:27 +02:00
setImage(last_path, last_httpUrl, last_filter, last_placeholder, last_size, lastCacheOnly);
2014-10-01 21:55:24 +02:00
FileLog.e("tmessages", e);
}
2014-07-10 02:15:58 +02:00
}
}
}
2014-08-29 23:06:04 +02:00
return true;
} else if (last_placeholder != null) {
drawRegion.set(x, y, x + w, y + h);
last_placeholder.setBounds(drawRegion);
if (isVisible) {
2014-10-01 21:55:24 +02:00
try {
last_placeholder.draw(canvas);
} catch (Exception e) {
if (currentPath != null) {
ImageLoader.getInstance().removeImage(currentPath);
currentPath = null;
}
2014-10-07 22:14:27 +02:00
setImage(last_path, last_httpUrl, last_filter, last_placeholder, last_size, lastCacheOnly);
2014-10-01 21:55:24 +02:00
FileLog.e("tmessages", e);
}
}
2014-08-29 23:06:04 +02:00
return true;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
2014-08-29 23:06:04 +02:00
return false;
}
public Bitmap getBitmap() {
if (currentImage != null && currentImage instanceof BitmapDrawable) {
return ((BitmapDrawable)currentImage).getBitmap();
} else if (isPlaceholder && last_placeholder != null && last_placeholder instanceof BitmapDrawable) {
return ((BitmapDrawable)last_placeholder).getBitmap();
}
return null;
}
public void setVisible(boolean value, boolean invalidate) {
if (isVisible == value) {
return;
}
isVisible = value;
2014-06-12 21:55:13 +02:00
if (invalidate && parentView != null) {
parentView.invalidate();
}
}
public boolean getVisible() {
return isVisible;
}
public boolean hasImage() {
2014-06-12 03:13:15 +02:00
return currentImage != null || last_placeholder != null || currentPath != null || last_httpUrl != null;
}
public void setAspectFit(boolean value) {
isAspectFit = value;
}
public void setParentView(View view) {
parentView = view;
}
protected Integer getTag() {
return tag;
}
protected void setTag(Integer tag) {
this.tag = tag;
}
public void setImageCoords(int x, int y, int width, int height) {
imageX = x;
imageY = y;
imageW = width;
imageH = height;
}
public int getImageX() {
return imageX;
}
public int getImageY() {
return imageY;
}
public int getImageWidth() {
return imageW;
}
public int getImageHeight() {
return imageH;
}
public boolean isInsideImage(float x, float y) {
return x >= imageX && x <= imageX + imageW && y >= imageY && y <= imageY + imageH;
}
public Rect getDrawRegion() {
return drawRegion;
}
public String getFilter() {
return last_filter;
}
public String getKey() {
return currentPath;
}
public void setForcePreview(boolean value) {
forcePreview = value;
}
}