Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用毕加索和自定义变换对象加载大型图像_Android_Picasso - Fatal编程技术网

Android 使用毕加索和自定义变换对象加载大型图像

Android 使用毕加索和自定义变换对象加载大型图像,android,picasso,Android,Picasso,在从Android Gallery(使用startActivityForResult)加载“大”图像(>1.5MB)时,我使用毕加索遇到内存不足异常 我使用一个自定义目标对象,因为我需要在位图准备就绪时对其进行预处理,而且我还使用一个自定义变换对象来缩放位图 问题是,由于内存不足异常,我的transform对象上的方法public Bitmap transform(Bitmap source)从未被调用,因此我没有机会对图像重新采样 但是,如果我使用.resize(maxWidth,maxHei

在从Android Gallery(使用startActivityForResult)加载“大”图像(>1.5MB)时,我使用毕加索遇到内存不足异常

我使用一个自定义目标对象,因为我需要在位图准备就绪时对其进行预处理,而且我还使用一个自定义变换对象来缩放位图

问题是,由于内存不足异常,我的transform对象上的方法
public Bitmap transform(Bitmap source)
从未被调用,因此我没有机会对图像重新采样

但是,如果我使用
.resize(maxWidth,maxHeight)
方法,那么它会加载图像OK。我猜Transform对象也是为了这个目的,但是似乎在resize之后调用了Transform方法,如果我不调用resize,那么它将以内存不足结束

问题是,使用resize时,我需要指定宽度和高度,但我需要缩放并保持纵横比


考虑到图像将从用户库中选择,因此它们可以更大或更小、纵向、方形或横向等,因此我需要自己的转换对象来执行需要我的应用程序的逻辑

Android开发者网站上有一篇非常好的文章,当我在加载大图像时遇到同样的问题时,这篇文章对我帮助很大

这篇文章很好地解释了错误的原因以及如何解决它。还有其他文章(请参见菜单)可用于缓存图像

我找到了一个解决办法

在我的Transform对象中,我需要将图像缩放(保持纵横比)到最大1024 x 768

除非调用
.resize(width,height)
对图像进行重采样,否则从未调用Transform对象

为了保持纵横比并使用resize,我调用
.centerInside()
。这样,图像将被缩放(重新采样以适应宽度、高度)

我给.resize(宽度、高度)的值是
Math.ceil(Math.sqrt(1024*768))
。 通过这种方式,我可以确保我的自定义变换对象的图像足够高,并且还可以避免内存不足的异常

更新:完整示例

在本例中,您将获得一幅符合最大宽度和最大高度界限(保持纵横比)的图像

这是我的自定义位图转换类:

import android.graphics.Bitmap;
import com.squareup.picasso.Transformation;

/**
 * Transformate the loaded image to avoid OutOfMemoryException
 */
public class BitmapTransform implements Transformation {

    private final int maxWidth;
    private final int maxHeight;

    public BitmapTransform(int maxWidth, int maxHeight) {
        this.maxWidth = maxWidth;
        this.maxHeight = maxHeight;
    }

    @Override
    public Bitmap transform(Bitmap source) {
        int targetWidth, targetHeight;
        double aspectRatio;

        if (source.getWidth() > source.getHeight()) {
            targetWidth = maxWidth;
            aspectRatio = (double) source.getHeight() / (double) source.getWidth();
            targetHeight = (int) (targetWidth * aspectRatio);
        } else {
            targetHeight = maxHeight;
            aspectRatio = (double) source.getWidth() / (double) source.getHeight();
            targetWidth = (int) (targetHeight * aspectRatio);
        }

        Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
        if (result != source) {
            source.recycle();
        }
        return result;
    }

    @Override
    public String key() {
        return maxWidth + "x" + maxHeight;
    }

}

宽度和高度的Math.ceil(Math.sqrt(1024*768))?是的,@DayDayHappy。我举了一个例子。我希望它能帮助我解决同样的问题,感谢那篇有用的帖子,我终于找到了解决办法。非常感谢,伙计。感谢这个转换是使用毕加索的正确实现方式。你可以调用
.fit()
,而不是
.resize()
,这会更快,但会降低图像质量。你能提供你所指文章的链接吗?
import android.graphics.Bitmap;
import com.squareup.picasso.Transformation;

/**
 * Transformate the loaded image to avoid OutOfMemoryException
 */
public class BitmapTransform implements Transformation {

    private final int maxWidth;
    private final int maxHeight;

    public BitmapTransform(int maxWidth, int maxHeight) {
        this.maxWidth = maxWidth;
        this.maxHeight = maxHeight;
    }

    @Override
    public Bitmap transform(Bitmap source) {
        int targetWidth, targetHeight;
        double aspectRatio;

        if (source.getWidth() > source.getHeight()) {
            targetWidth = maxWidth;
            aspectRatio = (double) source.getHeight() / (double) source.getWidth();
            targetHeight = (int) (targetWidth * aspectRatio);
        } else {
            targetHeight = maxHeight;
            aspectRatio = (double) source.getWidth() / (double) source.getHeight();
            targetWidth = (int) (targetHeight * aspectRatio);
        }

        Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
        if (result != source) {
            source.recycle();
        }
        return result;
    }

    @Override
    public String key() {
        return maxWidth + "x" + maxHeight;
    }

}