我正在尝试在CircularImageView中加载图像,但它给了我outOfMemory错误。 我正在使用以下代码进行CircularImageView:
CircularImageView.java
public class CircularImageView extends ImageView {
public CircularImageView(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getRoundedCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
public static Bitmap getRoundedCroppedBitmap(Bitmap bitmap, int radius) {
Bitmap
finalBitmap;
if (bitmap.getWidth() != radius || bitmap.getHeight() != radius)
finalBitmap = Bitmap.createScaledBitmap(bitmap, radius, radius,
false);
else
finalBitmap = bitmap;
Bitmap output = Bitmap.createBitmap(finalBitmap.getWidth(),
finalBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, finalBitmap.getWidth(),
finalBitmap.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(finalBitmap.getWidth() / 2 + 0.7f,
finalBitmap.getHeight() / 2 + 0.7f,
finalBitmap.getWidth() / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(finalBitmap, rect, rect, paint);
return output;
}
}
我在设计中使用它如下:
<com.almabay.almachat.circularImageView.CircularImageView
android:id="@+id/img_group"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_alignParentLeft="true" />
我从服务器获取图像并尝试使用Adapter在列表视图中显示它。此处使用了以下代码:
Picasso.with(context).load(image_url).error(R.drawable.default_avatar).into(viewHolder.imgGroup);
此处image_url是要在圆形图像视图中加载的图像的URL .ViewHolder.imgGroup是circularImageView。
请帮我解决问题。
答案 0 :(得分:2)
我看到你正在使用Picasso进行图像加载,为什么不使用毕加索图像变换。它实现起来非常简单: -
ImageView im = (ImageView) findViewById(R.id.img1);
Picasso.with(MainActivity2.this).load(R.drawable.kitten)
.transform(new CropCircleTransformation()).into(im);
它看起来像这个
您只需要添加转换类
import com.squareup.picasso.Transformation;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
public class CropCircleTransformation implements Transformation {
@Override public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
int width = (source.getWidth() - size) / 2;
int height = (source.getHeight() - size) / 2;
Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader =
new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
if (width != 0 || height != 0) {
// source isn't square, move viewport to center
Matrix matrix = new Matrix();
matrix.setTranslate(-width, -height);
shader.setLocalMatrix(matrix);
}
paint.setShader(shader);
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
source.recycle();
return bitmap;
}
@Override public String key() {
return "CropCircleTransformation()";
}
}
我们可以在此处找到更多转化https://github.com/wasabeef/picasso-transformations
答案 1 :(得分:1)
通常情况下,我会告诉您错误可能在任何地方,您可能正在泄漏。但是你在onDraw中制作了2个新的位图?所有3个都在记忆中?这不仅非常浪费,而且你的表现很糟糕 - 你甚至应该避免在onDraw中使用new,更不用说分配位图了。
把它扔出去并完全重写。你应该避免在这里使用drawable(特别是因为你无论如何都假设它是一个位图,这是一个坏主意),你应该接受位图的文件名或资源id并在其中读取/使用1 createBitmap进行缩放使用BitmapOptions命令。您应该在设置位图时执行此操作并保存结果,不要在始终调用的onDraw中进行缩放。您可以通过使用圆形剪切路径而不是使用porter duff模式和第二个画布来避免第3个位图。你可以用1位图完成所有这些,并且应该。