首页 文章

使用Picasso将图像调整为全宽和固定高度

提问于
浏览
153

我有一个垂直的LinearLayout,其中一个项目是使用Picasso加载的 ImageView . 我需要将图像的宽度提升到整个设备宽度,并显示图像的中心部分被固定高度(150dp)裁剪 . 我目前有以下代码:

Picasso.with(getActivity()) 
    .load(imageUrl) 
    .placeholder(R.drawable.placeholder) 
    .error(R.drawable.error) 
    .resize(screenWidth, imageHeight)
    .centerInside() 
    .into(imageView);

我应该将哪些值放入 screenWidthimageHeight (= 150dp)?

3 回答

  • 459

    您正在寻找:

    .fit().centerCrop()
    

    这意味着什么:

    • fit - 等到 ImageView 被测量并调整图像大小以与其大小完全匹配 .

    • centerCrop - 缩放符合宽高比的图像,直到它填充大小 . 裁剪顶部和底部或左右两侧,使其与尺寸完全匹配 .

  • 8

    This blog详细解释了毕加索的调整大小和拟合功能:https://futurestud.io/tutorials/picasso-image-resizing-scaling-and-fit .

    Image Resizing with resize(x, y)

    通常,如果您的服务器或API以您需要的精确尺寸提供图像,这是最佳选择,这是带宽,内存消耗和图像质量之间的完美折衷 .

    不幸的是,要求完美尺寸的图像并不总是在您的掌控之中 . 如果图像的大小很奇怪,您可以使用resize(horizontalSize,verticalSize)调用将图像的尺寸更改为更合适的尺寸 . 这将在ImageView中显示之前调整图像大小 .

    Picasso  
        .with(context)
        .load(UsageExampleListViewAdapter.eatFoodyImages[0])
        .resize(600, 200) // resizes the image to these dimensions (in pixel). does not respect aspect ratio
        .into(imageViewResize);
    

    Use of scaleDown()

    使用resize()选项时,Picasso也会升级您的图像 . 由于在不改善图像质量的情况下制作较小的图像可能会浪费计算时间,因此当原始图像的尺寸大于目标尺寸时,调用scaleDown(true)仅应用resize() .

    Picasso  
        .with(context)
        .load(UsageExampleListViewAdapter.eatFoodyImages[0])
        .resize(6000, 2000)
        .onlyScaleDown() // the image will only be resized if it's bigger than 6000x2000 pixels.
        .into(imageViewResizeScaleDown);
    

    Avoiding Stretched Images with Scaling

    现在,与任何图像处理一样,调整图像大小可能会使宽高比失真并使图像显示变得丑陋 . 在大多数用例中,您希望防止这种情况发生 . Picasso在这里给你两个缓解选择,可以是callCrop()或centerInside() .

    CenterCrop

    CenterCrop()是一种裁剪技术,可以缩放图像,使其填充ImageView的请求边界,然后裁剪额外的图像 . ImageView将完全填充,但可能无法显示整个图像 .

    Picasso  
        .with(context)
        .load(UsageExampleListViewAdapter.eatFoodyImages[0])
        .resize(600, 200) // resizes the image to these dimensions (in pixel)
        .centerCrop() 
        .into(imageViewResizeCenterCrop);
    

    CenterInside

    CenterInside()是一种裁剪技术,可以缩放图像,使两个维度都等于或小于ImageView的请求边界 . 图像将完全显示,但可能无法填满整个ImageView .

    Picasso  
        .with(context)
        .load(UsageExampleListViewAdapter.eatFoodyImages[0])
        .resize(600, 200)
        .centerInside() 
        .into(imageViewResizeCenterInside);
    

    最后,但并非最不重要:Picasso的适合()讨论的选项应该涵盖您对图像大小调整和缩放功能的需求 . Picasso有一个最后的辅助功能,它非常有用:fit() .

    Picasso  
        .with(context)
        .load(UsageExampleListViewAdapter.eatFoodyImages[0])
        .fit()
        // call .centerInside() or .centerCrop() to avoid a stretched image
        .into(imageViewFit);
    

    fit()测量目标ImageView的尺寸,并在内部使用resize()将图像大小减小到ImageView的尺寸 . fit()有两点需要了解 . 首先,调用fit()可以延迟图像请求,因为Picasso需要等到可以测量ImageView的大小 . 其次,您只能将fit()与ImageView一起用作目标(稍后我们将查看其他目标) .

    优点是图像处于尽可能低的分辨率,而不会影响其质量 . 较低的分辨率意味着要在缓存中保留较少的数据 . 这可以显着降低图像在应用内存占用中的影响 . 总之,如果您希望在更快的加载时间内降低内存影响,fit()是一个很好的工具 .

  • 0

    在某些情况下,fit()是无用的 . 必须等待宽度和高度测量结束之前 . 所以你可以使用globallayoutlistener . 例如;

    imageView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                public void onGlobalLayout() {
                    Picasso.with(getActivity())
                            .load(imageUrl)
                            .placeholder(R.drawable.placeholder)
                            .error(R.drawable.error)
                            .resize(screenWidth, imageHeight)
                            .fit
                            .centerInside()
                            .into(imageView);
                    view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                }
            });
    

相关问题