意外的“位图区域已被锁定” GetEncoderParameterList异常。有任何想法吗? [英] Unexpected "Bitmap Region is already Locked" exception with GetEncoderParameterList. Any ideas?

查看:579
本文介绍了意外的“位图区域已被锁定” GetEncoderParameterList异常。有任何想法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用这个来自Microsoft的示例代码来确定JPEG编码器可用的编码器选项。 (我试图解决的真正问题是看看我是否可以显式设置色度子采样参数)

I'm trying to use this sample code from Microsoft to determine what encoder options are available for the JPEG encoder. (The real problem I'm trying to solve is to see if I can set the Chroma subsampling parameters explicitly)

http://msdn.microsoft.com/en-us/library/bb882589.aspx

private void GetSupportedParameters(PaintEventArgs e)
{
    Bitmap bitmap1 = new Bitmap(1, 1);
    ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);
    EncoderParameters paramList = bitmap1.GetEncoderParameterList(jpgEncoder.Clsid);
    EncoderParameter[] encParams = paramList.Param;
    StringBuilder paramInfo = new StringBuilder();

    for (int i = 0; i < encParams.Length; i++)
    {
        paramInfo.Append("Param " + i + " holds " + encParams[i].NumberOfValues +
            " items of type " +
            encParams[i].ValueType + "\r\n" + "Guid category: " + encParams[i].Encoder.Guid + "\r\n");

    }
    e.Graphics.DrawString(paramInfo.ToString(), this.Font, Brushes.Red, 10.0F, 10.0F);
}

private ImageCodecInfo GetEncoder(ImageFormat format)
{

    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

    foreach (ImageCodecInfo codec in codecs)
    {
        if (codec.FormatID == format.Guid)
        {
            return codec;
        }
    }
    return null;
}

问题是,GetEncoderParameterList总是抛出一个异常:Bitmap Region is already锁定。

The problem is, "GetEncoderParameterList" always throws an exception: Bitmap Region Is already Locked.

我试着把代码放在我的程序的开始部分,而不是在on-paint事件处理程序中。一样。我试图改变位图上的位深度,并以其他方式创建位图,没有任何区别。

I tried putting the code at the very beginning of my program, and not in an on-paint event handler. Same thing. I tried changing the bit depth on the bitmap, and creating bitmaps in other ways, no difference.

任何想到为什么.NET会认为新创建的位图具有锁定区域?

Any idea why .NET would think a freshly created bitmap has a locked region?

更新!更多信息:如果我使用TIFF编码器,它不会失败:

Update! Some more info: If I use a TIFF encoder, it doesn't fail:

    Bitmap bitmap1 = new Bitmap(1, 1);
    ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.TIFF);  // TIFF instead of JPEG
    EncoderParameters paramList = bitmap1.GetEncoderParameterList(jpgEncoder.Clsid);
    EncoderParameter[] encParams = paramList.Param;

所以我认为这可能只是GetEncoderparameterList对于jpeg的bug / p>

So I think this may just be a bug/limitation of GetEncoderparameterList for jpeg....

推荐答案

我重复这个。异常消息是虚假的,这对于GDI +异常很常见。问题的根源是jpeg编解码器,GetEncoderParameterList()会查询它支持的参数列表。它返回的列表包含一个错误的条目,NumberOfValues为0.导致Marshal.AllocHGlobal()返回一个NULL,被误解为内存不足的异常,该错误被解释为Bitmap区域已被锁定例外。

I repro this. The exception message is bogus, that's common for GDI+ exceptions. The source of the problem is the jpeg codec, GetEncoderParameterList() queries it for the list of parameters it supports. The list it gets back contains one bad entry, the NumberOfValues is 0. That causes Marshal.AllocHGlobal() to return a NULL, misinterpreted as an out-of-memory exception, which is turn is misinterpreted as a "Bitmap region is already locked" exception.

呃,GDI +肯定是一团糟。这个问题几乎肯定是特定于GDI + 1.10版本的,该版本是随Vista首次发布的。也可能是Win7的具体情况,我已经看到几个论坛发布有关该操作系统上的JPEG编解码器的问题。

Ugh, GDI+ sure is a mess. This problem is almost certainly specific to GDI+ version 1.10, the version that first shipped with Vista. Could be Win7 specific too, I've seen several forum posting about problems with the JPEG codec on that operating system.

好吧,直到下一次,你才能做的事情Windows服务包变得可用,如果那样的话。要解决您的具体查询,不,可能不是。 GDI +知道的编码器参数列表在GdiPlusImaging.h SDK头文件中列出。唯一接近的是EncoderChrominanceTable,在.NET框架中以Encoder.ChrominanceTable.Guid形式提供。不知道是否与您正在寻找的内容接近。

Well, nothing you can do about it until the next Windows service pack becomes available, if then. To address your specific query, no, probably not. The list of encoder parameters that GDI+ knows about is listed in the GdiPlusImaging.h SDK header file. The only one that's close is "EncoderChrominanceTable", available as Encoder.ChrominanceTable.Guid in the .NET framework. No idea if that's close to what you are looking for.

您应该真的考虑WPF JpegBitmapEncoder类,这是对GDI =的重大改进。

You should really consider the WPF JpegBitmapEncoder class, a major improvement over GDI=.

这篇关于意外的“位图区域已被锁定” GetEncoderParameterList异常。有任何想法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆