【问题标题】:Resizing images on Windows Phone 7 on thread pool thread?在线程池线程上调整 Windows Phone 7 上的图像大小?
【发布时间】:2011-07-13 22:51:07
【问题描述】:

我正在编写一个处理大量图像的 Windows Phone 7 应用程序 - 这些图像的范围可以从几百像素到 1080P(未来可能更高)。

图片非常耗费资源,所以我在显示它们之前在手机上缓存+调整图片大小。

这意味着在用户输入图像存储的 IP 地址后的第一次设置时,我可以要求他们等待几分钟,同时所有图像都被检索/调整大小/缓存。从那时起,他们可以有漂亮而活泼的表现。

目前,我的缓存管理器通过 Uri 的字典和文件位置来跟踪图像。我有一个队列,一次最多处理 5 个图像(异步 Web 请求,调整大小在线程池线程上半完成)。

我遇到的问题是 Silverlight 中的 WritableBitmap 类是一个 UI 元素,这意味着我必须通过 Dispatcher 转换到 UI 线程来进行实际的调整大小,这很愚蠢并且会减慢整个过程 - 这也意味着我的缓存管理器实际上是单线程的。

缓存管理器(线程池)-> 异步 Web 请求(线程池)-> 回调(线程池)-> 调整大小(UI 线程)-> 将缓存作业标记为完成(线程池)。

我一直在寻找一个第三方库,它将 A) 在 Windows Phone 7 上编译和运行 B) 能够通过操作流或字节数组来调整各种格式的图像大小,而不依赖于 UI 线程.

有人有这方面的经验吗?

干杯,

泰勒

【问题讨论】:

  • 有没有机会在下载图片时使用网络服务来调整图片大小?
  • 它们来自我无法控制的外部系统 =/
  • 您可以将 URL 传递给一个网络服务,该服务将执行下载+调整大小,然后将较小的图像传回 Windows 手机?我想这就是达米安所说的。
  • 啊,对,那太慢了抱歉。调整它们大小的实际行为已经足够快了……我只知道如果我不必转换到 UI 线程来执行它,它可以快得多。我只需要一个可以在字节级别上使用 png 和 jpeg 的库,它可以在 UI 以外的线程上使用。
  • 我已经搜索了一整天,还没有找到任何东西 - 我确实找到了 LeadTools,它是一套支持 WP7 的大量成像工具 - leadtools.com/sdk/silverlight/windows-phone.htm - 他们的调整大小类可以运行后台线程,但不幸的是它是 A)比 WriteableBitmap 慢了很多,B)看起来在某些时候它们在调整大小期间正在转换到 UI 线程(屏幕闪烁白色 - 很好的迹象是 UI 线程被阻止了)。

标签: c# .net image windows-phone-7


【解决方案1】:

我认为您的问题不在于性能,而在于您将如何显示图像。我认为最好始终显示默认缩略图,然后在后台作业调整其大小后更新缩略图。该应用应该可以更快地使用。

【讨论】:

    【解决方案2】:

    Tyler - 您提到在首次启动时,应用程序确实从 IP 地址检索图像(我认为是在互联网上)?

    这意味着在用户输入图像存储的 IP 地址后的第一次设置时,我可以要求他们等待几分钟,同时所有图像都被检索/调整大小/缓存。从那时起,他们可以有漂亮而活泼的表现。

    如果这是正确的,我认为一些答案在创建代理时所建议的实际上是一个可行的解决方案。我会这样组织它:

    您的应用程序 -> 对代理处理程序的 Web 请求

    string imageUrl = HttpUtility.UrlEncode("http://[user's_ip]/path_to_image.png");
    http://domain.com/your_proxy.ashx?users_image_url=imageUrl 
    

    您在后端的代理处理程序应请求图像、调整其大小并将调整后的图像返回给您的应用程序。

    你的应用程序 -> 缓存返回的调整大小的图像

    根据需要循环...

    更新:

    事实证明,有一种方法可以使用原生 WriteableBitmap 类在 UI 线程之外调整 WP7 上的图像大小。有一个名为 .SaveJpeg() 的方法允许这样做,我们目前在 WP7 应用程序 CitySourced 中使用它。您的代码应如下所示:

    wb.SaveJpeg(stream, width, height, orientation, quality);
    

    唯一的遗憾是它只能通过编写 .JPG 文件来工作,并且不支持 .PNG。让我知道这是否适用于您的用例。

    【讨论】:

    • 附带说明,我认为服务器可以比设备更快地调整图像大小,因此这可能是比让设备处理调整大小更快的解决方案。此外,调整大小的图像会比下载原始的、更大的图像更快地到达设备。
    • 不错的尝试,但您没有阅读其余的 cmets 吗? :p 我的应用程序通过 wifi 在家庭网络上使用。我不想建立对互联网的需求。
    • 您可以构建处理程序以在 Intranet 网站上工作(可通过私有 IP 地址或主机文件修改访问),它的工作方式与面向公众的处理程序相同。
    【解决方案3】:

    您想在服务器上显示文件吗?

    如果是,我认为你选择了错误的方法来解决这个问题。传输重图像然后调整它们的大小是没有意义的。我建议在服务器上保持低分辨率和高分辨率。

    如果没有,我帮不了你。我找到了this article,但我想你已经看到了。

    【讨论】:

      【解决方案4】:

      http://www.dtksoft.com/dtkimage.php 这适用于所有文件格式,并且与 windows Mobile 兼容

      【讨论】:

      • 没有提到对 WP7 的支持,不是免费的,你听起来好像没有任何个人经验,所以我想你不能评论速度等。
      【解决方案5】:

      试试 Réne Schulte 创建的 http://writeablebitmapex.codeplex.com/。它具有比 SDK 附带的 WriteableBitmap 更好的性能。

      【讨论】:

      • 仍然依赖作为 UI 元素的 WriteableBitmap,因此根本无法回答我的问题。
      • 其实WriteableBitmap的SaveJpeg方法可以在UI线程外调用。
      【解决方案6】:

      为了减少下载大小并减轻手机 CPU 的处理负担,我会将这项工作推送到 Web 服务。

      例如,您可以在某处在线http://webimageresizer.codeplex.com/ 托管类似开源 WebImageResizer 代码之类的服务 - 例如。在免费的 AppHarbor 服务器上。

      或者您可以使用商业(免费增值)服务,例如:

      其中任何一个都可以让您在具有超快连接的服务器上快速处理图像,并通过有限的数据连接将较小的图像传送到手机。

      【讨论】:

      • 抱歉,这对我的应用程序不可行。该应用程序是一个 Xbox Media Center 遥控器,旨在通过 Wifi 使用(它可以通过 3G 等方式使用,但没有多大意义)。我真的不想强迫人们将他们的媒体库图像上传到网络服务,然后再回到他们的手机来使用我的应用程序。我也不想要求他们有互联网连接才能使用我的应用程序,
      • 感谢您的解释。现在我明白你在说什么了......我认为你不会通过从 UI 线程中改变它来获得任何改进。您可以通过找到更快的调整大小算法来使其更快,但是问题中的“单线程”措辞不是问题 - 从根本上讲,您使用的是具有单核 CPU 的手机(以及一些图形处理可从 UI 中获取)。
      • 我认为让这种感觉更快的唯一方法是:1)在缓存期间向用户显示一些反馈,2)让用户在缓存完成之前开始使用应用程序(带有 placekitten 缩略图) , 3) 再次查看 Media Center API - 有没有办法向它询问缩略图?, 4) 除了调整大小之外,查看图像解码器库以查看下载的图像是否已经包含缩略图(例如,JPEG 经常在 JFIF 流中嵌入拇指)。提前抱歉 - 我猜你已经尝试过所有这些事情!
      • 1) 用户当前会看到一个屏幕,解释为什么需要缓存,以及需要缓存多少图像的计数器 - 我想如果我提出原因,那么希望他们不会那么介意。 2)在缓存完成之前,我不能让他们使用该应用程序,因为当图像被缓存/调整大小时,调整大小是在 UI 线程上完成的(参见第一篇文章),因此他们会在不知道原因的情况下获得不可接受的 UI 口吃。 3) 没有办法向 Xbox Media Center 询问较小的图像,最后 4) 这不是一个坏主意,必须考虑 :)。此处缓存屏幕截图:imgup.co.nz/1751
      • 酷 :) 1)如果您每隔几秒钟显示一张新图片,那么他们可能会更喜欢这条消息。在 2)查看您的屏幕截图时,我认为可能可以进行按需图像处理,而不是预先下载……但从根本上说,这都是您的选择。祝你好运!
      【解决方案7】:

      ImageTools 库既支持 WP7 又支持图像大小调整,因此使用它可能会更成功。

      【讨论】:

      • ImageTools 不支持 WP7 上的 PNG,也没有提供我能找到的任何调整大小的实用程序(它们确实提供了一个接口,但没有实现)。
      • 如果您查看源代码控制中的最新版本(在 CodePlex 上),它现在在 WP7 上有一个 PNG 实现。调整大小功能在 ExtendedImage_Operations 类文件中作为 ExtendedImage 类的静态 Resize 方法提供。
      • 不幸的是,Resize 方法将 IImageResizer 接口作为参数,而且我看不到任何 IImageResizer 的实现。
      • 默认的IImageResizerImageTools.Filtering.NearestNeighborResizer,它在 ImageTools.Filtering 程序集中(在 WP7 下也可用)。
      • 嗯,它到处抛出异常,而且速度慢得要命(没有文档,所以我可能做错了什么,但是当我只是尝试将图像源设置为内存流时,它会抛出异常)。我开始认为 Silverlight WriteableBitmap 类至少可以本地执行其调整大小的代码和/或硬件加速,因为还没有第三方解决方案接近(即使它们在自己的线程上运行)。
      猜你喜欢
      • 2012-08-06
      • 1970-01-01
      • 2014-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-23
      相关资源
      最近更新 更多