标签: gdi+

GDI +,JPEG Image to MemoryStream中发生一般错误

这似乎是整个网络上一个臭名昭着的错误.因为我的情景不适合,所以我无法找到问题的答案.将图像保存到流时会抛出异常.

奇怪的是这与png完美配合,但是jpg和gif给出了上述错误,这是相当混乱的.

最相似的问题涉及将图像保存到没有权限的文件.具有讽刺意味的是,解决方案是使用内存流,因为我正在做....

public static byte[] ConvertImageToByteArray(Image imageToConvert)
{
    using (var ms = new MemoryStream())
    {
        ImageFormat format;
        switch (imageToConvert.MimeType())
        {
            case "image/png":
                format = ImageFormat.Png;
                break;
            case "image/gif":
                format = ImageFormat.Gif;
                break;
            default:
                format = ImageFormat.Jpeg;
                break;
        }

        imageToConvert.Save(ms, format);
        return ms.ToArray();
    }
}
Run Code Online (Sandbox Code Playgroud)

更多细节到例外.造成这么多问题的原因是缺乏解释:(

System.Runtime.InteropServices.ExternalException was unhandled by user code
Message="A generic error occurred in GDI+."
Source="System.Drawing"
ErrorCode=-2147467259
StackTrace:
   at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters    encoderParams)
   at System.Drawing.Image.Save(Stream stream, ImageFormat format)
   at Caldoo.Infrastructure.PhotoEditor.ConvertImageToByteArray(Image imageToConvert) in C:\Users\Ian\SVN\Caldoo\Caldoo.Coordinator\PhotoEditor.cs:line 139
   at …
Run Code Online (Sandbox Code Playgroud)

c# gdi+

314
推荐指数
16
解决办法
45万
查看次数

使用MaxHeight和MaxWidth约束按比例调整图像大小

System.Drawing.Image.

如果图像宽度或高度超过最大值,则需要按比例调整大小.调整大小后,需要确保宽度或高度都不超过限制.

宽度和高度将调整大小,直到它不会自动超过最大值和最小值(可能的最大尺寸)并保持比率.

.net c# gdi+ image-processing winforms

120
推荐指数
3
解决办法
14万
查看次数

Image.Save(..)抛出GDI +异常,因为内存流已关闭

我有一些二进制数据,我想保存为图像.当我尝试保存图像时,如果用于创建图像的内存流在保存之前关闭,则会引发异常.我这样做的原因是因为我正在动态创建图像,因此我需要使用内存流.

这是代码:

[TestMethod]
public void TestMethod1()
{
    // Grab the binary data.
    byte[] data = File.ReadAllBytes("Chick.jpg");

    // Read in the data but do not close, before using the stream.
    Stream originalBinaryDataStream = new MemoryStream(data);
    Bitmap image = new Bitmap(originalBinaryDataStream);
    image.Save(@"c:\test.jpg");
    originalBinaryDataStream.Dispose();

    // Now lets use a nice dispose, etc...
    Bitmap2 image2;
    using (Stream originalBinaryDataStream2 = new MemoryStream(data))
    {
        image2 = new Bitmap(originalBinaryDataStream2);
    }

    image2.Save(@"C:\temp\pewpew.jpg"); // This throws the GDI+ exception.
}
Run Code Online (Sandbox Code Playgroud)

有没有人对如何在关闭流的情况下保存图像有任何建议?我不能依赖开发人员记住在保存图像后关闭流.实际上,开发人员没有使用内存流生成映像的IDEA(因为它发生在其他地方的其他代码中).

我真的很困惑:(

c# gdi+ image exception

104
推荐指数
3
解决办法
9万
查看次数

在Windows窗体上绘制一个像素

我试图打开Windows窗体上的单个像素.

graphics.DrawLine(Pens.Black, 50, 50, 51, 50); // draws two pixels

graphics.DrawLine(Pens.Black, 50, 50, 50, 50); // draws no pixels
Run Code Online (Sandbox Code Playgroud)

API真的应该有一个方法来设置一个像素的颜色,但我没有看到一个.

我正在使用C#.

.net c# gdi+ pixel winforms

86
推荐指数
4
解决办法
9万
查看次数

在Bitmap.Save方法中GDI +中发生了一般错误

我正在努力上传并将该图像的缩略图副本保存在缩略图文件夹中.

我正在使用以下链接:

http://weblogs.asp.net/markmcdonnell/archive/2008/03/09/resize-image-before-uploading-to-server.aspx

newBMP.Save(directory + "tn_" + filename);   
Run Code Online (Sandbox Code Playgroud)

导致异常"GDI +中发生了一般错误."

我试图给予文件夹权限,还试图在保存时使用新的单独的bmp对象.

编辑:

    protected void ResizeAndSave(PropBannerImage objPropBannerImage)
    {
        // Create a bitmap of the content of the fileUpload control in memory
        Bitmap originalBMP = new Bitmap(fuImage.FileContent);

        // Calculate the new image dimensions
        int origWidth = originalBMP.Width;
        int origHeight = originalBMP.Height;
        int sngRatio = origWidth / origHeight;
        int thumbWidth = 100;
        int thumbHeight = thumbWidth / sngRatio;

        int bannerWidth = 100;
        int bannerHeight = bannerWidth / sngRatio;

        // Create a new …
Run Code Online (Sandbox Code Playgroud)

c# system.drawing gdi+

58
推荐指数
6
解决办法
13万
查看次数

在玻璃上渲染控件:找到解决方案,需要双缓冲/完善

我(终于!)找到了一种在玻璃上渲染Windows.Forms控件的方法,它似乎没有任何重大缺点,也没有任何大的实现时间.它受到Coded 的这篇文章的启发,它基本上解释了如何本地覆盖控件绘制以绘制它们.

我使用该方法将控件渲染为位图,并使用GDI +和适当的Alpha通道将其绘制回NativeWindow的绘制区域.实现很简单,但可以完善可用性,但这不是这个问题的重点.然而,结果非常令人满意:

在玻璃上的真正文本框

但是,有两个区域需要修复才能真正使用.

  1. 双缓冲,因为这个叠加图像和真实控件之间的闪烁是频繁和可怕的(用代码测试自己).将基本控件设置为双缓冲SetStyles(this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true)不起作用,但我怀疑我们可以通过一些试验和错误使其工作.
  2. 某些控件不起作用.我已经能够完成以下工作:

    • 文本框
    • MaskedComboBox
    • ComboBox(DropDownStyle == DropDownList)
    • 列表框
    • CheckedListBox
    • 列表显示
    • 树视图
    • 的DateTimePicker
    • 的MonthCalendar

    但我不能让这些工作,虽然我不明白为什么不.我有根据的猜测是,实际的NativeWindow句柄我引用了整个控件,而我需要引用它的"输入"(文本)部分,可能是一个孩子.有关如何获取输入窗口句柄的WinAPI专家的任何帮助都是受欢迎的.

    • ComboBox(DropDownStyle!= DropDownList)
    • 的NumericUpDown
    • RichTextBox的

但修复双缓冲将是可用性的主要关注点.

这是一个示例用法:

new GlassControlRenderer(textBox1);
Run Code Online (Sandbox Code Playgroud)

这是代码:

public class GlassControlRenderer : NativeWindow
{
    private Control Control;
    private Bitmap Bitmap;
    private Graphics ControlGraphics;

    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case 0xF: // WM_PAINT
            case 0x85: // WM_NCPAINT
            case 0x100: // WM_KEYDOWN
            case 0x200: // WM_MOUSEMOVE
            case 0x201: …
Run Code Online (Sandbox Code Playgroud)

.net c# winapi gdi+ aero

46
推荐指数
1
解决办法
3087
查看次数

在C++ Win32中创建透明窗口

我正在创建一个非常简单的Win32 C++应用程序,它的唯一目的就是只显示一个半透明的PNG.窗口不应该有任何镶边,并且所有不透明度都应该在PNG本身中控制.

我的问题是当窗口下的内容发生变化时,窗口不会重新绘制,因此PNG的透明区域与应用程序最初启动时窗口下的内容"卡住".

这是我设置新窗口的行:

hWnd = CreateWindowEx(WS_EX_TOPMOST, szWindowClass, szTitle, WS_POPUP, 0, height/2 - 20, 40, 102, NULL, NULL, hInstance, 0);
Run Code Online (Sandbox Code Playgroud)

对于RegisterClassEx的调用,我有这个背景集:

wcex.hbrBackground = (HBRUSH)0;
Run Code Online (Sandbox Code Playgroud)

这是WM_PAINT消息的处理程序:

 case WM_PAINT:
 {
   hdc = BeginPaint(hWnd, &ps);
   Gdiplus::Graphics graphics(hdc);
   graphics.DrawImage(*m_pBitmap, 0, 0);
   EndPaint(hWnd, &ps);
   break;
 }
Run Code Online (Sandbox Code Playgroud)

需要注意的一点是,应用程序始终停靠在屏幕左侧,不会移动.但是,当用户打开,关闭或移动其下的窗口时,应用程序下面的内容可能会发生变化.

当应用程序首次启动时,它看起来很完美.PNG的透明(和类似透明)部分完美展现.但是,当应用程序下面的背景发生变化时,后台不会更新,它会在应用程序首次启动时保持不变.实际上,WM_PAINT(或WM_ERASEBKGND在后台更改时不会被调用).

我已经玩了很长一段时间了,已经接近100%正确,但不是那里.例如,我尝试将背景设置为(HBRUSH)NULL_BRUSH,我尝试处理WM_ERASEBKGND.

当窗口下的内容发生变化时,可以做些什么来重新绘制窗口?

c++ winapi transparency gdi+ alphablending

44
推荐指数
2
解决办法
5万
查看次数

如何找到实际的可打印区域?(的PrintDocument)

为什么发现这个神奇的矩形如此困难?

在OnPrintPage事件中,我有PrintPageEventArgs,我试图在最大可打印区域的范围内使用图形绘制.

我尝试过使用PageBounds,PrintableArea,Graphics.VisibleClipBounds等.所有都无法始终获得绘图区域,尤其是从横向切换到纵向布局时.从Landscape切换到Portrait时,PrintableArea似乎永远不会改变.

我还注意到,根据我是否正在进行打印预览和实际打印,如何设置Graphics.VisibleClipBounds存在差异.在预览中它始终显示纵向宽度/高度,因此我必须检查它是否是预览,并且当它是横向时我必须手动交换宽度/高度.

我需要一个算法来计算可打印区域,因为它与当前的图形上下文有关,而不是在实际绘图中没有使用的任意理论打印区域.


我关心的是处理Graphics矩阵偏移.到目前为止,我注意到如何根据以下因素使用硬边缘预翻译图形上下文之间存在严重的不一致:

  • 如果OriginAtMargins为真或假(不符合我的想法)
  • 如果我要打印到打印机,或者使用PrintPreviewControl(我必须检查这是打印预览还是打印到页面以正确处理翻译)
  • 如果我在家里使用我的打印机或在工作时使用我的打印机(两者都表现不同)

有没有一种标准的方法来处理这个问题?我应该重置矩阵吗?当我将OriginAtMargins设置为true时,Graphics会预先转换为84,84,但我的边距是100,100.艰难的利润是16,16.它不应该被翻译成100,100吗?因为0,0应该在页面边界,而不是硬边距.

基本上我的方法应该总是在获得最佳的可打印矩形.我只需要一种与设备无关的一致方式来确保我的绘图原点(0,0)位于页面的左上角,以便上面的Rectangle对我有用.

c# printing gdi+ printdocument

43
推荐指数
1
解决办法
5万
查看次数

C# - 将图像输出到响应输出流,给出GDI +错误

将图像输出到输出流时,是否需要临时存储?在将图像保存到文件时,我收到通常与文件夹权限错误相关的"通用GDI +"错误.

我正在对图像做的唯一事情是添加一些文本.即使我直接输出图像而没有修改,我仍然会得到错误.例如,这样做会给我错误:

using (Bitmap image = new Bitmap(context.Server.MapPath("images/stars_5.png")))
{
    image.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Png);
}
Run Code Online (Sandbox Code Playgroud)

在运行带有IIS 7.5和ASP.NET 2.0的Windows 7的本地计算机上,一切正常.问题出现在运行带有IIS 6和ASP.NET 2.0的Windows Server 2003的QA服务器上.

给出错误的行是:

image.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Png);
Run Code Online (Sandbox Code Playgroud)

这是堆栈跟踪:

[ExternalException (0x80004005): A generic error occurred in GDI+.]
   System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams) +378002
   System.Drawing.Image.Save(Stream stream, ImageFormat format) +36
   GetRating.ProcessRequest(HttpContext context) in d:\inetpub\wwwroot\SymInfoQA\Apps\tools\Rating\GetRating.ashx:54
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
Run Code Online (Sandbox Code Playgroud)

c# asp.net gdi+

41
推荐指数
2
解决办法
5万
查看次数

在不使用Graphics对象的情况下测量String?

我使用像素作为我的字体的单位.在一个地方,我正在执行命中测试以检查用户是否在屏幕上的某些文本的边界矩形内点击了.我需要使用像MeasureString这样的东西.不幸的是,执行命中测试的代码深入到一个无法访问Graphics对象甚至是一个对象的库中Control.

如何在不使用Graphics类的情况下获取给定字体的字符串的边界框?为什么Graphics我的字体以像素为单位时甚至需要一个对象?

c# fonts text gdi+

40
推荐指数
3
解决办法
3万
查看次数