【问题标题】:ASP.NET libwebp.dll how to save WebP image to diskASP.NET libwebp.dll 如何将 WebP 图像保存到磁盘
【发布时间】:2018-10-09 05:24:12
【问题描述】:

我已经为 WebP 构建了 libwebp.dll,使用 these instructions(我下载了这个 source code

我已将libwebp.dll 文件添加到我的项目的bin 文件夹中。

然后我添加了这个代码 (found here):

Private Declare Function WebPEncodeBGRA Lib "libwebp.dll" (ByVal rgba As IntPtr, ByVal width As Integer, ByVal height As Integer, ByVal stride As Integer, ByVal quality_factor As Single, ByRef output As IntPtr) As Integer
Private Declare Function WebPFree Lib "libwebp.dll" (ByVal p As IntPtr) As Integer

Private Sub Encode()
    Dim source As Bitmap = New Bitmap(Server.MapPath("images\") + "audio.png")
    Dim data As BitmapData = source.LockBits(New Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
    Dim webp_data As IntPtr
    Dim i As Integer = WebPEncodeBGRA(data.Scan0, source.Width, source.Height, data.Stride, 80, webp_data)

    WebPFree(webp_data)
End Sub

我得到错误:

试图加载格式不正确的程序。 (HRESULT 异常:0x8007000B)

我也做了什么(在下面 Dai 的 cmets 之后):

  • 我为 64 位架构构建了 dll,如下所示:nmake /f Makefile.vc CFG=release-dynamic RTLIBCFG=dynamic OBJDIR=output ARCH=x64 (also see here)
  • 我检查了有问题的应用程序池的 IIS,它的属性 Enable32-Bit Applications 设置为 False
  • 我正在运行 Windows 10 64 位
  • Environment.Is64BitProcessEnvironment.Is64BitOperatingSystem 在代码隐藏中评估为 True

如何对图像进行编码并将编码后的图像以 WebP 格式保存到磁盘?

这是我正在使用的图像文件:

【问题讨论】:

  • 该错误是由于尝试在 64 位主机进程中加载​​ 32 位 DLL 引起的,反之亦然。我假设您的网络服务器以 64 位运行,但您只构建了 libwebp.dll 的 32 位版本。
  • 也有可能是相反的情况:IIS 以 32 位运行,无法加载您的 64 位 DLL。
  • 我刚刚在 IIS 中检查了有问题的应用程序池的应用程序池设置,它的属性 Enable32-Bit Applications 设置为 False,所以我想这也不是...

标签: asp.net windows vb.net image webp


【解决方案1】:

如何对图像进行编码并将编码后的图像以 WebP 格式保存到磁盘?

在转换过程之后,您需要编组非托管内存,以​​便您可以在托管代码中使用数据。

Public Sub Encode()
    Dim source As Bitmap = New Bitmap(Server.MapPath("images\audio.png"))
    'Hold bitmap data
    Dim bmpData As BitmapData = source.LockBits(New Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb)

    'Create a pointer for webp data
    Dim webpDataSrc As IntPtr

    'Store resulting webp data length after conversion
    Dim webpDataLen As Integer = WebPEncodeBGRA(bmpData.Scan0, source.Width, source.Height, bmpData.Stride, 80, webpDataSrc)

    'Create a managed byte array with the size you just have
    Dim webpDataBin As Byte() = New Byte(webpDataLen - 1){}

    'Copy from unmanaged memory to managed byte array you created
    System.Runtime.InteropServices.Marshal.Copy(webpDataSrc, webpDataBin, 0, webpDataLen)

    'Write byte array to a file
    System.IO.File.WriteAllBytes(Server.MapPath("images\audio.webp"), webpDataBin)

    'Free
    WebPFree(webpDataSrc)

    source.Dispose()
End Sub

顺便说一句,您说您使用的命令nmake /f Makefile.vc CFG=release-dynamic RTLIBCFG=dynamic OBJDIR=output ARCH=x64 是可以的。我也可以使用该命令编译库(版本 1.0.0)。但是我 100% 肯定 zipped libwebp.dll here 是 32 位的,而不是 64 位的。

确保您启动了正确的环境来生成 64 位二进制文​​件。

【讨论】:

  • 好的...这似乎保存了 webp 图像!最后一步:您是从哪个环境开始创建 64 位二进制文​​件的?我尝试了x64 Native Tools Command Prompt for Visual Studio 2017,还尝试了以 64 位模式运行的常规 Windows 命令提示符,并尝试了 Windows Powershell。这些都不适合我。
  • @Flo 与您相同的环境和相同的逗号。这是带有dumpbin 输出的输出目录截图:img.imgur.com/5BXzyuN.png
  • 好吧...这让我发疯...你能在某个地方与我分享你拥有的已编译的 64 位 dll 吗?然后我可以关闭这个线程并分配赏金,然后找出为什么它不能在我的机器上运行....提前谢谢你!
  • 嗯...我想在你和其他海报之间分享赏金,但这在 SO 上是不可能的。由于另一张海报是第一个并提供了关键部分,webp 的编码失败了,我将奖励他赏金并开始另一个赏金,让你奖励你 50 分......希望你理解 :-)
  • @Flo 没关系,但对我来说根本不需要额外的赏金。谢谢。
【解决方案2】:

我对你的样本也有问题,所以我检查了来源,看起来你使用了不同的方法,然后在样本中,不知道为什么。

所以我改变并看起来有效。

    <DllImport("libwebp.dll", CallingConvention:=CallingConvention.Cdecl)>
Private Shared Function WebPEncodeBGRA(ByVal rgba As IntPtr, ByVal width As Integer, ByVal height As Integer, ByVal stride As Integer, ByVal quality_factor As Single, <Out> ByRef output As IntPtr) As Integer
End Function


<DllImport("libwebp.dll", CallingConvention:=CallingConvention.Cdecl)>
Private Shared Function WebPFree(ByVal p As IntPtr) As Integer
End Function

并导入

Imports System.Runtime.InteropServices

我已经使用了来自 Thise instructions 'libwebp-0.6.0.zip\x64\bin' 的下载 libwebp-0.6.0.zip 的 dll,它可以工作。

当我尝试从 在此处下载已编译和压缩的 libwebp.dll。这是我正在使用的图像文件:

得到了完全相同的异常,看起来不是 64

对于图片我不确定,可能你需要反转它

            'data.strinde = webp_data 'not sure what is webp_data ewxacly, but you can check
        'data.Scan0 = webp_data 'not sure what is webp_data ewxacly, but you can check
        source.UnlockBits(data)
        source.Save(Server.MapPath("images\") + "audio.png")

【讨论】:

  • 谢谢,0.6.0 dll 似乎确实有助于通过第一个错误。您正在保存source 变量,但它需要保存webp_data 变量,我该怎么做?您是否能够为 x64 编译 1.0.0 libwebp.dll?我宁愿不使用 0.6.0 beta 版本,也不知道为什么编译不正确。
  • 嗨!再次感谢您对此的帮助。我现在收到错误There is insufficient system memory in resource pool 'internal' to run this query.,我认为这是因为我没有清除内存。我看到你代码中的WebPFree方法是空的,你知道我应该在里面输入什么来清除内存吗?
猜你喜欢
  • 2016-09-30
  • 1970-01-01
  • 2021-10-13
  • 2011-10-19
  • 2011-01-17
  • 1970-01-01
  • 2011-10-31
相关资源
最近更新 更多