java – 滑入加载到SimpleTarget中不遵守指定的宽度和高度

前端之家收集整理的这篇文章主要介绍了java – 滑入加载到SimpleTarget中不遵守指定的宽度和高度前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用Glide加载图像,调整大小并通过SimpleTarget< Bitmap>将其保存到文件中.这些图像将上传到Amazon S3,但除此之外.我正在上传之前调整图像大小以节省尽可能多的用户带宽.对于我的应用程序需要1024像素宽的图像绰绰有余,所以我使用以下代码来实现这一点:
final String to = getMyImageUrl();
final Context appCtx = context.getApplicationContext();

Glide.with(appCtx)
        .load(sourceImageUri)
        .asBitmap()
        .into(new SimpleTarget<Bitmap>(1024,768) {
            @Override
            public void onResourceReady(Bitmap resource,GlideAnimation<? super Bitmap> glideAnimation) {
                try {
                    FileOutputStream out = new FileOutputStream(to);
                    resource.compress(Bitmap.CompressFormat.JPEG,70,out);
                    out.flush();
                    out.close();
                    MediaScannerConnection.scanFile(appCtx,new String[]{to},null,null);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

它几乎完美地工作,但生成的图像的大小不是1024像素宽.使用尺寸为4160 x 2340像素的源图像对其进行测试,得到的保存图像的尺寸为2080 x 1170像素.

我尝试使用传递给新SimpleTarget< Bitmap>(350,350)的宽度和高度参数,并使用这些参数得到的图像尺寸为1040 x 585像素.

我真的不知道如何使Glide尊重传递的尺寸.事实上,我想按比例调整图像大小,以便将较大的尺寸(宽度或高度)限制为1024像素,较小的尺寸相应调整大小(我相信我必须找到获得原始图像的方法)尺寸,然后将宽度和高度传递给SimpleTarget,但要做到这一点,我需要Glide尊重传递的宽度和高度!).

有没有人知道发生了什么?我正在使用Glide 3.7.0.

由于这个问题本身可能对尝试使用Glide调整大小和保存图像的人有用,我相信提供我的实际“解决方案”符合每个人的利益,该解决方案依赖于自动保存调整大小的图像的新SimpleTargetimplementation:

import android.graphics.Bitmap;

import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;

import java.io.FileOutputStream;
import java.io.IOException;

public class FileTarget extends SimpleTarget<Bitmap> {
    public FileTarget(String fileName,int width,int height) {
        this(fileName,width,height,Bitmap.CompressFormat.JPEG,70);
    }
    public FileTarget(String fileName,int height,Bitmap.CompressFormat format,int quality) {
        super(width,height);
        this.fileName = fileName;
        this.format = format;
        this.quality = quality;
    }
    String fileName;
    Bitmap.CompressFormat format;
    int quality;
    public void onResourceReady(Bitmap bitmap,GlideAnimation anim) {
            try {
                FileOutputStream out = new FileOutputStream(fileName);
                bitmap.compress(format,quality,out);
                out.flush();
                out.close();
                onFileSaved();
            } catch (IOException e) {
                e.printStackTrace();
                onSaveException(e);
            }
    }
    public void onFileSaved() {
        // do nothing,should be overriden (optional)
    }
    public void onSaveException(Exception e) {
        // do nothing,should be overriden (optional)
    }

}

使用它很简单:

Glide.with(appCtx)
        .load(sourceImageUri)
        .asBitmap()
        .into(new FileTarget(to,1024,768) {
            @Override
            public void onFileSaved() {
                // do anything,or omit this override if you want
            }
        });

解决方法

经过一夜好眠,我才明白了!我在Glide的github页面上偶然发现了一个有问题的问题,但我没有意识到:我在解释中遗漏了一些内容,我现在已经完全理解了10个小时后的内容.你永远不应该低估睡眠的力量!但我离题了.以下是 Glide’s Github issue tracker的答案:

Sizing the image usually has two phases:

  • Decoding/Downsampler read image from stream with inSampleSize
  • Transforming/BitmapTransformation take the Bitmap and match the exact
    target size

The decoding is always needed and is included in the flow,
the default case is to match the target size with the “at least”
downsampler,so when it comes to the transformation the image can be
downsized more without quality loss (each pixel in the source will
match at least 1.0 pixels and at most ~1.999 pixels) this can be
controlled by asBitmap().at least|atMost|asIs|decoder(with
downsampler)

The transformation and target size is automatic by default,but only
when using a ViewTarget. When you load into an ImageView the size of
that will be detected even when it has match_parent. Also if there’s
no explicit transformation there’ll be one applied from scaleType.
Thus results in a pixel perfect Bitmap for that image,meaning 1 pixel
in Bitmap = 1 pixel on screen resulting in the best possible quality
with the best memory usage and fast rendering (because there’s no
pixel mapping needed when drawing the image).

With a SimpleTarget you take on these responsibilities by providing a
size on the constructor or via override() or implementing getSize if
the sizing info is async-ly available only.

To fix your load add a transformation: .fitCenter|centerCrop(),your
current applied transformation is .dontTransform()
(Answer by 07001)

我对此答案感到困惑,因为:

With a SimpleTarget you take on these responsibilities by providing a
size on the constructor or via override() or implementing getSize if
the sizing info is async-ly available only.

由于我通过了尺寸,我认为我已经覆盖了这个尺寸,这样的尺寸应该得到尊重.我错过了这个重要的概念:

  • Decoding/Downsampler read image from stream with inSampleSize
  • Transforming/BitmapTransformation take the Bitmap and match the exact
    target size

还有这个:

To fix your load add a transformation: .fitCenter|centerCrop(),your
current applied transformation is .dontTransform()

现在,我将它拼凑在一起是有道理的. Glide只是对图像进行下采样(如Róbert所解释的尺寸图像流程中的第一步),它给出了具有近似尺寸的图像.让我说Glide在这方面非常聪明.通过在调整大小之前使用下采样方法,可以避免在内存中处理不必要的大位图并提高调整大小的质量,因为缩减到精确的大小会损害太多“重要”像素!

由于我没有对此加载管道应用任何转换,因此在第一步(下采样)中停止了大小调整流程,并且生成的图像仅具有与我的预期目标大小相近的大小.

为了解决这个问题,我刚刚应用了一个.fitCenter()变换,如下所示:

Glide.with(appCtx)
        .load(sourceImageUri)
        .asBitmap()
        .fitCenter()
        .into(new FileTarget(to,or omit this override if you want
            }
        });

生成的图像现在具有1024 x 576像素的尺寸,这正是我所期望的.

Glide是一个非常酷的图书馆!

猜你在找的Java相关文章