如何调整 xamarin.forms 中的图像大小?
Posted
技术标签:
【中文标题】如何调整 xamarin.forms 中的图像大小?【英文标题】:How to resize images in xamarin.forms? 【发布时间】:2021-08-20 20:50:18 【问题描述】:我正在研究 xamarin.forms。我必须从图库中选择图像,然后调整它们的大小,然后将它们上传到服务器上。但我不知道如何以给定的特定尺寸调整所选图像的大小? 请告诉我我该怎么做?
【问题讨论】:
看到这个帖子:forums.xamarin.com/discussion/37681/… 虽然你需要从德语翻译一点:) 嗨,Jason,使用了 Bitmap,但是我如何在 xamarin.forms 中使用 Bitmap。我需要为 xamarin.forms 中的位图使用什么参考? 阅读弗雷迪在帖子中的笔记。他将其编写为一个共享项目——位图参考位于代码的 android 部分,而不是 ios。如果您不想使用共享项目,则需要重构以使用特定于平台的项目和 DI。 【参考方案1】:这可以与流(如果您使用媒体插件https://github.com/jamesmontemagno/MediaPlugin)或标准字节数组一起使用。
// If you already have the byte[]
byte[] resizedImage = await CrossImageResizer.Current.ResizeImageWithAspectRatioAsync(originalImageBytes, 500, 1000);
// If you have a stream, such as:
// var file = await CrossMedia.Current.PickPhotoAsync(options);
// var originalImageStream = file.GetStream();
byte[] resizedImage = await CrossImageResizer.Current.ResizeImageWithAspectRatioAsync(originalImageStream, 500, 1000);
【讨论】:
不确定是否过时,但CrossImageResizer
不是您提到的库的一部分【参考方案2】:
我尝试使用CrossImageResizer.Current...
,但在Media Plugin
中没有找到它。相反,我发现了一个名为 MaxWidthHeight
的选项,它仅在您还添加 PhotoSize = PhotoSize.MaxWidthHeight
选项时才有效。
例如:
var file = await CrossMedia.Current.PickPhotoAsync(new PickMediaOptions() PhotoSize = PhotoSize.MaxWidthHeight, MaxWidthHeight = 600 );
var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions PhotoSize = PhotoSize.MaxWidthHeight, MaxWidthHeight = 600 );
【讨论】:
【参考方案3】:可悲的是,没有一个好的跨平台图像调整器(我在发这篇文章时发现的)。图像处理并非真正设计为在 iOS 和 Android 的跨平台环境中进行。使用特定于平台的代码在每个平台上执行此操作会更快、更清晰。您可以使用依赖注入和 DependencyService(或任何其他服务或 IOC)来做到这一点。
AdamP 对如何做到这一点给出了很好的回应Platform Specific Image Resizing
【讨论】:
您能在此处添加代码吗?因为链接/页面会随着时间的推移而消失..【参考方案4】:这是从上面链接中获取的代码。
iOS
public class MediaService : IMediaService
public byte[] ResizeImage(byte[] imageData, float width, float height)
UIImage originalImage = ImageFromByteArray(imageData);
var originalHeight = originalImage.Size.Height;
var originalWidth = originalImage.Size.Width;
nfloat newHeight = 0;
nfloat newWidth = 0;
if (originalHeight > originalWidth)
newHeight = height;
nfloat ratio = originalHeight / height;
newWidth = originalWidth / ratio;
else
newWidth = width;
nfloat ratio = originalWidth / width;
newHeight = originalHeight / ratio;
width = (float)newWidth;
height = (float)newHeight;
UIGraphics.BeginImageContext(new SizeF(width, height));
originalImage.Draw(new RectangleF(0, 0, width, height));
var resizedImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
var bytesImagen = resizedImage.AsJPEG().ToArray();
resizedImage.Dispose();
return bytesImagen;
安卓
public class MediaService : IMediaService
public byte[] ResizeImage(byte[] imageData, float width, float height)
// Load the bitmap
BitmapFactory.Options options = new BitmapFactory.Options();// Create object of bitmapfactory's option method for further option use
options.InPurgeable = true; // inPurgeable is used to free up memory while required
Bitmap originalImage = BitmapFactory.DecodeByteArray(imageData, 0, imageData.Length, options);
float newHeight = 0;
float newWidth = 0;
var originalHeight = originalImage.Height;
var originalWidth = originalImage.Width;
if (originalHeight > originalWidth)
newHeight = height;
float ratio = originalHeight / height;
newWidth = originalWidth / ratio;
else
newWidth = width;
float ratio = originalWidth / width;
newHeight = originalHeight / ratio;
Bitmap resizedImage = Bitmap.CreateScaledBitmap(originalImage, (int)newWidth, (int)newHeight, true);
originalImage.Recycle();
using (MemoryStream ms = new MemoryStream())
resizedImage.Compress(Bitmap.CompressFormat.Png, 100, ms);
resizedImage.Recycle();
return ms.ToArray();
WinPhone
public class MediaService : IMediaService
private MediaImplementation mi = new MediaImplementation();
public byte[] ResizeImage(byte[] imageData, float width, float height)
byte[] resizedData;
using (MemoryStream streamIn = new MemoryStream(imageData))
WriteableBitmap bitmap = PictureDecoder.DecodeJpeg(streamIn, (int)width, (int)height);
float Height = 0;
float Width = 0;
float originalHeight = bitmap.PixelHeight;
float originalWidth = bitmap.PixelWidth;
if (originalHeight > originalWidth)
Height = height;
float ratio = originalHeight / height;
Width = originalWidth / ratio;
else
Width = width;
float ratio = originalWidth / width;
Height = originalHeight / ratio;
using (MemoryStream streamOut = new MemoryStream())
bitmap.SaveJpeg(streamOut, (int)Width, (int)Height, 0, 100);
resizedData = streamOut.ToArray();
return resizedData;
编辑:如果您已经在项目中使用 FFImageLoading,那么您可以将其用于您的平台。
https://github.com/luberda-molinet/FFImageLoading
【讨论】:
嗨henda,iOS示例缺少此方法ImageFromByteArray(imageData);。 嗨,Matas,最后我从未使用过这些方法,我只是为 Android 开发,所以从未测试过 iOS 实现。我最终使用了来自github.com/luberda-molinet/FFImageLoading 的 FFImageLoading,因为它具有调整大小的方法,输出质量不错。 试试 UIImage originalImage = UIImage.LoadFromData(NSData.FromArray(imageData));以上是关于如何调整 xamarin.forms 中的图像大小?的主要内容,如果未能解决你的问题,请参考以下文章
如何Xamarin.Forms调整水平的ListView的大小
Xamarin.Forms android - 调整控件大小以考虑可访问性设置