GetEncoderParameterList意外的"位图区域已锁定"异常.有任何想法吗?

4 c# graphics bitmap .net-4.0 visual-studio-2010

我正在尝试使用Microsoft的此示例代码来确定JPEG编码器可用的编码器选项.(我想解决的真正问题是看看我是否可以明确设置色度子采样参数)

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;
}
Run Code Online (Sandbox Code Playgroud)

问题是,"GetEncoderParameterList"总是抛出异常:位图区域已经锁定.

我尝试将代码放在程序的最开头,而不是在on-paint事件处理程序中.一样.我尝试改变位图上的位深度,并以其他方式创建位图,没有区别.

知道为什么.NET认为新创建的位图有一个锁定区域?


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

    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;
Run Code Online (Sandbox Code Playgroud)

所以我认为这可能只是jpeg的GetEncoderparameterList的错误/限制....

Han*_*ant 5

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

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

好吧,在下一个Windows服务包可用之前,你无能为力.要解决您的特定查询,不,可能不是.GDI +知道的编码器参数列表列在GdiPlusImaging.h SDK头文件中.唯一接近的是"EncoderChrominanceTable",在.NET框架中以Encoder.ChrominanceTable.Guid的形式提供.不知道这是否接近你想要的东西.

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

  • Windows 10也没有. (4认同)