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

查看:104
本文介绍了意外的“位图区域已被锁定"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 + "
" + "Guid category: " + encParams[i].Encoder.Guid + "
");

    }
    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 Locked.

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

我尝试将代码放在程序的开头,而不是在绘制事件处理程序中.一样.我试着改变位图上的位深,用其他方式创建位图,没有区别.

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 for jpeg 的一个错误/限制......

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

推荐答案

我重复了这个.异常消息是伪造的,这在 GDI+ 异常中很常见.问题的根源是jpeg编解码器,GetEncoderParameterList()查询它支持的参数列表.它返回的列表包含一个错误条目,NumberOfValues 为 0.这导致 Marshal.AllocHGlobal() 返回 NULL,被误解为内存不足异常,进而被误解为位图区域已被锁定" 异常.

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 Service Pack 可用之前,您无能为力.要解决您的特定查询,不,可能不是.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天全站免登陆