gpt4 book ai didi

c# - 将图像异步加载到网格中

转载 作者:行者123 更新时间:2023-11-30 16:43:31 25 4
gpt4 key购买 nike

我正在开发一个小型应用程序,它将获取 RAW 图像文件,将它们转换为低质量的 JPEG,然后将这些 JPEG 作为缩略图加载到网格中。

我的问题:我遇到了在转换图像时 UI 被阻塞的问题。在对每个图像进行转换之后,我正在动态添加控件以在网格中托管这些图像。此外,我在代码隐藏中使用 ControlProperties ViewModel 将这些图像绑定(bind)到我的 Image 控件的 Source

我的编码:

在这里,我正在创建我的 ControlProperties View 模型的一个新实例,并在内部对 ImageSource 进行图像转换。

cp = new ControlProperties()
{
ImageId = controlCount += 1, ImageSource = ThumbnailCreator.CreateThumbnail(imagePath)
};

我的问题:

鉴于图像需要一段时间才能加载,我需要在转换图像并将其添加到我的网格中时完全控制我的 UI,但我根本没有做对。有人可以帮我提供一些建议或代码片段让我继续吗?

我的 ThumbnailCreator

using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;

namespace SomeProjName
{
public class ThumbnailCreator
{
private static string imageLocation;
private static int currentImage;
public static BitmapImage CreateThumbnail(string oldImagePath)
{
ConvertHighQualityRAWImage(oldImagePath);

if (imageLocation != string.Empty && imageLocation != null)
return OpenImage(imageLocation);
else return null;
}

//Creates low quality JPG image from RAW image
private static void ConvertHighQualityRAWImage(string oldImagePath)
{

BitmapImage image = new BitmapImage(new Uri(oldImagePath));
var encoder = new JpegBitmapEncoder() { QualityLevel = 17 };
encoder.Frames.Add(BitmapFrame.Create(image));

using (var filestream = new FileStream(GetImageLocation(), FileMode.Create))
encoder.Save(filestream);

image.UriSource = null;
image.StreamSource = null;
image = null;

GC.WaitForPendingFinalizers();
GC.Collect();
}

//Returns low quality JPG thumbnail to calling method
private static BitmapImage OpenImage(string imagePath)
{
BitmapImage image = new BitmapImage();
image.BeginInit();
image.DecodePixelWidth = 283;
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = new Uri(imagePath, UriKind.Relative);
image.EndInit();

DeleteImage();
return image;
}

private static string GetImageLocation()
{
imageLocation = Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "thumbnails")).FullName + GetCurrentImage();
return imageLocation;
}

private static string GetCurrentImage()
{
return "\\" + (currentImage += 1).ToString() + ".jpg";
}

private static void DeleteImage()
{
if (File.Exists(imageLocation))
File.Delete(imageLocation);
}
}
}

最佳答案

您不需要将缩略图保存到文件中。使用 MemoryStream 代替:

public class ThumbnailCreator
{
public static BitmapImage CreateThumbnail(string imagePath)
{
BitmapFrame source;

using (var stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read))
{
source = BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}

var encoder = new JpegBitmapEncoder() { QualityLevel = 17 };
encoder.Frames.Add(BitmapFrame.Create(source));

var bitmap = new BitmapImage();

using (var stream = new MemoryStream())
{
encoder.Save(stream);
stream.Position = 0;

bitmap.BeginInit();
bitmap.DecodePixelWidth = 283;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
}

bitmap.Freeze();
return bitmap;
}

中间的编码和解码过程似乎都不是必需的,所以你可以简单地写成这样:

public class ThumbnailCreator
{
public static BitmapImage CreateThumbnail(string imagePath)
{
var bitmap = new BitmapImage();

using (var stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read))
{
bitmap.BeginInit();
bitmap.DecodePixelWidth = 283;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
}

bitmap.Freeze();
return bitmap;
}
}

如果要异步调用 CreateThumbnail 方法,请使用 Task.Run():

cp.ImageSource = await Task.Run(() => ThumbnailCreator.CreateThumbnail(fileName));

关于c# - 将图像异步加载到网格中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44846767/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com