简体   繁体   English

使用毕加索将图像调整为全宽和固定高度

[英]Resize image to full width and fixed height with Picasso

I have a vertical LinearLayout where one of the items is an ImageView loaded using Picasso.我有一个垂直的 LinearLayout,其中一项是使用 Picasso 加载的ImageView I need to rise the image's width to the full device width, and to display the center part of the image cropped by a fixed height (150dp).我需要将图像的宽度增加到整个设备宽度,并显示按固定高度 (150dp) 裁剪的图像的中心部分。 I currently have the following code:我目前有以下代码:

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

Which values should I put into screenWidth and imageHeight (=150dp)?我应该将哪些值放入screenWidthimageHeight (=150dp)?

You are looking for:您正在寻找:

.fit().centerCrop()

What these mean:这些是什么意思:

  • fit - wait until the ImageView has been measured and resize the image to exactly match its size. fit - 等到ImageView被测量并调整图像大小以完全匹配其大小。
  • centerCrop - scale the image honoring the aspect ratio until it fills the size. centerCrop - 按照纵横比缩放图像,直到它填满尺寸。 Crop either the top and bottom or left and right so it matches the size exactly.裁剪顶部和底部或左右,使其大小完全匹配。

This blog explains Picasso's resize and fit functions in detail: https://futurestud.io/tutorials/picasso-image-resizing-scaling-and-fit . 该博客详细介绍了毕加索的调整大小和拟合功能: https : //futurestud.io/tutorials/picasso-image-resizing-scaling-and-fit

Image Resizing with resize(x, y) 使用调整大小(x,y)调整图像大小

Generally it's optimal if your server or API deliver the image in the exact dimensions you need, which are a perfect trade-off between bandwidth, memory consumption and image quality. 通常,如果您的服务器或API以所需的准确尺寸交付图像,则是最佳选择,这是带宽,内存消耗和图像质量之间的完美平衡。

Unfortunately, it's not always in your control to request images in the perfect dimensions. 不幸的是,请求完美尺寸的图像并不总是在您的控制范围内。 If the images are in a weird size you can use the resize(horizontalSize, verticalSize) call to change the dimensions of your image into a more suitable size. 如果图像的尺寸很奇怪,则可以使用resize(horizo​​ntalSize,verticalSize)调用将图像的尺寸更改为更合适的尺寸。 This will resize the image before displaying it in the ImageView. 在将其显示在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() 使用scaleDown()

When using the resize() option Picasso will also upscale your image. 使用resize()选项时,毕加索也会放大图像。 Since making a small image bigger without improving the quality of the image can be wasted computing time, call scaleDown(true) to only apply the resize() when the original image has larger dimensions than the target size. 由于在不提高图像质量的情况下使小图像变大会浪费计算时间,因此请调用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 通过缩放避免拉伸图像

Now, as with any image manipulation, resizing images can really distort the aspect ratio and uglify the image display. 现在,与任何图像处理一样,调整图像大小确实可以使宽高比失真并使图像显示丑陋。 In most of your use cases, you want to prevent this from happening. 在大多数用例中,您想防止这种情况发生。 Picasso gives you two mitigation choices here, either call centerCrop() or centerInside(). 毕加索在此处为您提供了两种缓解措施,即调用centerCrop()或centerInside()。

CenterCrop 中心作物

CenterCrop() is a cropping technique that scales the image so that it fills the requested bounds of the ImageView and then crops the extra. CenterCrop()是一种裁剪技术,可缩放图像,以使其填充ImageView的请求范围,然后裁剪多余的图像。 The ImageView will be filled completely, but the entire image might not be displayed. ImageView将被完全填充,但是可能不会显示整个图像。

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

CenterInside 中心内

CenterInside() is a cropping technique that scales the image so that both dimensions are equal to or less than the requested bounds of the ImageView. CenterInside()是一种缩放技术,可缩放图像以使两个尺寸均等于或小于ImageView的请求范围。 The image will be displayed completely, but might not fill the entire ImageView. 该图像将完全显示,但可能不会填满整个ImageView。

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

Last, but not least: Picasso's fit() The discussed options should cover your needs for functionality regarding image resizing and scaling. 最后但并非最不重要的一点:毕加索的fit()讨论的选项应满足您对图像调整大小和缩放功能的需求。 There is one last helper functionality of Picasso, which can be very useful: fit(). 毕加索的最后一个辅助功能是非常有用的:fit()。

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

fit() is measuring the dimensions of the target ImageView and internally uses resize() to reduce the image size to the dimensions of the ImageView. fit()正在测量目标ImageView的尺寸,并在内部使用resize()将图像尺寸减小到ImageView的尺寸。 There are two things to know about fit(). 关于fit()有两点要了解。 First, calling fit() can delay the image request since Picasso will need to wait until the size of the ImageView can be measured. 首先,调用fit()可能会延迟图像请求,因为毕加索需要等待直到可以测量ImageView的大小。 Second, you only can use fit() with an ImageView as the target (we'll look at other targets later). 其次,您只能将fit()与ImageView一起用作目标(稍后我们将介绍其他目标)。

The advantage is that the image is at the lowest possible resolution, without affecting its quality. 优点是图像的分辨率尽可能低,而不会影响其质量。 A lower resolution means less data to be hold in the cache. 较低的分辨率意味着要保留在缓存中的数据更少。 This can significantly reduce the impact of images in the memory footprint of your app. 这可以大大减少图像对应用程序内存占用的影响。 In summary, if you prefer a lower memory impact over a little faster loading times, fit() is a great tool. 总而言之,如果您希望对内存的影响较小,而不是更快的加载时间,那么fit()是一个不错的工具。

In some case the fit() is useless.在某些情况下, fit() 是无用的。 Before you must wait for the width and height measurement to end.在您必须等待宽度和高度测量结束之前。 So you can use globallayoutlistener.所以你可以使用 globallayoutlistener。 for example;例如;

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);
                imageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM