【问题标题】:Generic GDI+ Error when saving hBitmap as Bitmap将 hBitmap 保存为位图时出现一般 GDI+ 错误
【发布时间】:2011-04-10 12:04:54
【问题描述】:

我正在编写自己的 DIB/BMP 解码器(我知道已经有其他解码器,但我正在学习图像处理)并且我已设法将像素存储在指针中并获取用于编写 hBitmap 的相关尺寸,但此错误不断出现:

Generic Error Occured in GDI+.

下面是堆栈跟踪和代码:

at System.Drawing.Image.FromHbitmap(IntPtr hbitmap, IntPtr hpalette)
at System.Drawing.Image.FromHbitmap(IntPtr hbitmap)
at pcx_reader.bmp.BitmapFromPCXBits(Int32 height, Int32 width, Int32 numplanes, Int32 bpp, IntPtr pixels)
at pcx_reader.MainWindow.button1_Click(Object sender, RoutedEventArgs e)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
at System.Windows.Controls.MenuItem.InvokeClickAfterRender(Object arg)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at pcx_reader.App.Main()
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

代码:

    public Bitmap BitmapFromPCXBits(int height, int width, int numplanes, int bpp, IntPtr pixels)
    {
        IntPtr hDc = CreateCompatibleDC(IntPtr.Zero);
        IntPtr hBitmap = IntPtr.Zero;
        IntPtr hOldBitmap = IntPtr.Zero;

        hBitmap = CreateBitmap(width, height, (uint)numplanes, (uint)bpp, pixels);
        hOldBitmap = SelectObject(hDc, hBitmap);

        System.Drawing.Bitmap bmp = System.Drawing.Bitmap.FromHbitmap(hBitmap);
        //Bitmap bmp = new Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format1bppIndexed, pixels);

        DeleteObject(SelectObject(hDc, hOldBitmap));

        DeleteDC(hDc);

        return bmp;
    }

我不知道出了什么问题,但我对 PCX 文件使用了类似的功能,但除了单色图像外,它们都失败了,渲染得很好。如果有人能提供帮助,我将不胜感激。

【问题讨论】:

    标签: c# bitmap gdi+ hbitmap


    【解决方案1】:

    如果不知道您的调用中有哪些输入参数,很难判断...

    无论如何要尝试几件事:

    • 检查 CreateBitmap() 的返回值!
    • 确保位平面的数量正确
    • 改用位图构造函数(使用 GDI+ 枚举位图格式,如果已知平面数,则可能不需要将其作为参数传递)

      // 这在 C++ 中有效

      HDC hOff = ::CreateCompatibleDC( NULL );

      位图oDaBigOne(g_iWidth, g_iHeight, PixelFormat32bppARGB);

      HBITMAP hBmit = NULL;

      颜色 oCol(0, 0, 0, 0);

      oDaBigOne.GetHBITMAP(oCol, &hBmit);

      HGDIOBJ hSave = ::SelectObject( hOff, hBmit );

    【讨论】:

    • 谢谢,我现在正在使用带有 stride、bpp、intptr 等的 System.Drawing.Bitmap 构造函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多