在Windows XP计算机上,以下代码抛出System.ComponentModel.Win32Exception,并显示消息"操作已成功完成"
System.Drawing.Icon icon = new System.Drawing.Icon("icon.ico");
Run Code Online (Sandbox Code Playgroud)
我可以阻止程序崩溃
try
{
System.Drawing.Icon icon = new System.Drawing.Icon("icon.ico");
}
catch(System.ComponentModel.Win32Exception ex)
{
if (ex.NativeErrorCode != 0)
{
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
但当然没有设置图标.
完整的堆栈跟踪是
at System.Drawing.Icon.Initialize(Int32 width, Int32 height)
at System.Drawing.Icon..ctor(String fileName, Int32 width, Int32 height)
at System.Drawing.Icon..ctor(String fileName)
at hermes.Window1..ctor() in D:\\projects\\hermesclient\\hermesWPF\\hermes\\Window1.xaml.cs:line 50"
Run Code Online (Sandbox Code Playgroud)
第50行是我发布的原始行.
这是一个WPF应用程序,在Windows 7机器上,代码工作正常.
编辑:原来这个图标在Windows XP中根本不起作用,添加256色版本似乎已经修复了它.
从文档Image.FromHbitmap()的http://msdn.microsoft.com/en-us/library/k061we7x%28VS.80%29.aspx:
FromHbitmap方法制作GDI位图的副本; 因此,您可以在创建新图像后立即使用GDIDeleteObject方法释放传入的GDI位图.
这非常明确地说明,一旦创建了Bitmap实例,就可以使用DeleteObject立即删除位图句柄.
Image.FromHbitmap()然而,看看使用Reflector 的实现,它表明它是围绕GDI +函数的一个非常薄的包装器GdipCreateBitmapFromHBITMAP().
有对GDI +平板API函数相当稀少的文档,但http://msdn.microsoft.com/en-us/library/ms533971%28VS.85%29.aspx表示,GdipCreateBitmapFromHBITMAP()对应于Bitmap::Bitmap()接受一个构造函数HBITMAP和HPALETTE作为参数.
http://msdn.microsoft.com/en-us/library/ms536314%28VS.85%29.aspx上此版本Bitmap::Bitmap()构造函数的文档有这样的说法:
您负责删除GDI位图和GDI调色板.但是,在删除GDI + Bitmap :: Bitmap对象或超出范围之前,不应删除GDI位图或GDI调色板.
不要将GDI位图或位图构造函数传递给当前(或以前)选择到设备上下文中的GDI位图或GDI调色板.
此外,可以在源代码中看到GdiPlusBitmap.h中GDI +的C++部分,所讨论的Bitmap::Bitmap()构造函数本身就是GdipCreateBitmapFromHBITMAP()来自平面API 的函数的包装器:
inline
Bitmap::Bitmap(
IN HBITMAP hbm,
IN HPALETTE hpal
)
{
GpBitmap *bitmap = NULL;
lastResult = DllExports::GdipCreateBitmapFromHBITMAP(hbm, hpal, &bitmap);
SetNativeImage(bitmap);
}
Run Code Online (Sandbox Code Playgroud)
我不能轻易看到的是GdipCreateBitmapFromHBITMAP()这个功能的核心实现,但文档中的两个评论似乎是矛盾的..Net文档说我可以立即删除位图句柄,并且GDI +文档说必须保留位图句柄,直到删除包装对象,但两者都基于相同的GDI +函数.
此外,GDI +文档警告不要使用当前或之前选择到设备上下文中的源HBITMAP.虽然我可以理解为什么当前不应该将位图选择到设备上下文中,但我不明白为什么会出现使用先前选择到设备上下文中的位图的警告.这似乎会阻止使用标准GDI在内存中创建的GDI +位图.
所以,总结一下:
GdipCreateBitmapFromHBITMAP()是复制源位图还是只保留原始句柄?我正在开发一个.NET 3.5赢形式的程序和我碰到与文本绘制一个"有趣"的问题.
我正在实现一个文本编辑控件,它使用DrawString()和StringFormat.GenericTypographic(以下称为GT)绘制文本.当用户键入时,行中较早的单词(或单词组)随机地左右移动.
它似乎可能是舍入误差 - 受影响的块看起来在水平平面中移动一个像素,因为字母被添加到线的末端.如果我使用StringFormat.GenericDefault(GD),则不会发生这种情况,但字符渲染的准确性会降低,这是不可接受的.
我推断我可以慢慢地将GD改为GT(每个设置都在MSDN中进行讨论,显然可以在调试器中进行检查)并查看哪些FormatFlags或其他设置导致了这一点并从那里开始.但是,如果我拿一份GD的副本,改变所有的属性,使它与GT相同,那么字符的位置是完全不同的 - 这两个所谓的相同对象的行为显然是不一样的.
像恕我直言的东西太多,.net Reflector表明StringFormat只是非托管对象的包装器,我只能假设并非所有这些属性都暴露给.net软件.
任何人都可以提出任何可能对我有用的建议吗 我知道TextRenderer可能会提供另一种渲染方法,但我在设计过程的早期就打了折扣(虽然我实际上不能记住现在的问题......).
编辑
我用于渲染的代码如下:
sForm = new StringFormat(StringFormat.GenericTypographic);
sForm.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
using (SolidBrush brush = new SolidBrush(frmt.ForegroundColour))
context.DrawString(line.Text, frmt.DisplayFont, brush, new PointF(horizontal, height), sForm);
Run Code Online (Sandbox Code Playgroud) 我们有很多C#2.0代码,它们严重依赖于System.Drawing命名空间.还有一些WinGDI依赖项(通过互操作).
您如何建议解决制作功能相当的Silverlight版本代码的问题?我们希望尽可能多地重用代码,因为我们希望继续开发代码的两个版本.
也许你可以推荐一些文章/书籍?
更新:代码是一个非可视组件.不是申请.没有第三方依赖项.
我正在创建一个应用程序,可以在用户设计时可视化相框.为了创建框架,我绘制了4个多边形,它们代表木材的物理位,并使用TextureBrush来填充它.
这适用于左边和上边缘.但是,对于底边和右边,此方法不起作用.在我看来,TextureBrush是从图像上的点(0,0)平铺而不是在我绘制的多边形内.结果,图块不与多边形对齐.通过调整图像的大小,我可以让瓷砖完美排列.
如何创建一个任意定位的多边形并用平铺图像填充它,从多边形内的点(0,0)开始,而不是画布?
如果有更好的解决方案,我没有附加到FillPolygon和TextureBrush.
例

为什么要评估false?
Color.FromArgb(255, 255, 255, 255) == Color.White
Run Code Online (Sandbox Code Playgroud)
更新它的设计.
这是结构中反编译Equals函数的副本Color:
public override bool Equals(object obj)
{
//probably failure to convert from C++ source,
//the following line should be invalid in C#, nevermind
if (obj is Color)
{
Color color = (Color) obj;
if (((this.value == color.value) &&
(this.state == color.state)) &&
(this.knownColor == color.knownColor))
{
return ((this.name == color.name) ||
(((this.name != null) && (color.name != null)) &&
this.name.Equals(this.name)));
}
}
return false;
} …Run Code Online (Sandbox Code Playgroud) 我正在使用.Net工具进行2D绘图.System.Drawing.Font使用a GetHeight()返回高度(以像素为单位).我错过了GetWidth()检索宽度!我该怎么用?
我以前从没做过绘图,因此我没有遇到任何问题。我似乎无法使此代码的输出正常工作。
该文件正在保存,但未在文本上绘制。谁能看到我做错了什么?
编辑:一个愚蠢的错误-图像的背景为白色(画笔颜色为!)。文本未居中,但是正如我所期望的那样。有什么想法吗?:)
编辑:图像在下面。

谢谢
Bitmap myBitmap = new Bitmap(@"C:\Users\Scott\desktop\blank.bmp");
Graphics g = Graphics.FromImage(myBitmap);
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.DrawString("My\nText",
new Font("Tahoma", 20),
Brushes.White,
new PointF(0, 0));
StringFormat strFormat = new StringFormat();
strFormat.Alignment = StringAlignment.Center;
strFormat.LineAlignment = StringAlignment.Center;
g.DrawString("My\nText",
new Font("Tahoma", 20), Brushes.White,
new RectangleF(0, 0, 500, 500),
strFormat);
myBitmap.Save(@"C:\Users\Scott\desktop\blank1.bmp");
Run Code Online (Sandbox Code Playgroud) 我正在使用.Net绘图来绘制图表.它本质上是一个堆积条形图.我的问题是我想减少填充样式中的线条数量,这样就可以将其缩小以使其更清晰.我环顾四周,但没有遇到任何可以帮助我的事情.
我绘制一个矩形,然后用一个舱口盖来填充它,但由于图像尺寸,影院填充变得不那么清晰了.谢谢你的任何建议.
hatchStyles和brush类型存储在db中,我使用辅助函数来返回它们.所以我画了矩形,拿到画笔后我填充了矩形.基本上我想扩大舱口填充,如果可以做到的话.
g.DrawRectangle(gridpen, startX, startY, BOREHOLE_RECT_WIDTH, layerRectHeight);
brush = GetBoreholeBrush(l.SoilTypeMatrixLevel1Id.PrimaryBrushType,
l.SoilTypeMatrixLevel1Id.PrimaryFillStyle,
l.SoilTypeMatrixLevel1Id.PrimaryColour);
g.FillRectangle(brush, startX, startY, BOREHOLE_RECT_WIDTH, layerRectHeight);
Run Code Online (Sandbox Code Playgroud)
和getBrush函数; 画笔类型,阴影样式和颜色存储在数据库中并用于创建返回的画笔:
//===================================
private Brush GetBoreholeBrush(string BrushType, string HatchStyle, string Colour)
//===================================
{
//Decide on what brush type has been chosen.
Brush brush;
if (BrushType.ToLower() == BrushTypes.HatchBrush.ToString().ToLower())
{
brush = new HatchBrush(GetHatchStyle(HatchStyle),
Color.Black, ColorTranslator.FromHtml(Colour));
}
else if (BrushType.ToLower() == BrushTypes.SolidBrush.ToString().ToLower())
{
brush = new HatchBrush(GetHatchStyle(HatchStyle),
Color.Black, ColorTranslator.FromHtml(Colour));
}
else if (BrushType.ToLower() == BrushTypes.TextureBrush.ToString().ToLower())
{
brush = new HatchBrush(GetHatchStyle(HatchStyle),
Color.Black, ColorTranslator.FromHtml(Colour));
}
else …Run Code Online (Sandbox Code Playgroud) 我的程序批量处理一些图像.我目前需要读取图像的exif方向标记,将其旋转到正确的方向,进行一些处理并保存图像,没有任何EXIF方向标记,但是具有正确的旋转.(或使用EXIF标记)正确定位)
我正在阅读EXIF并使用此库旋转:
var bmp = new Bitmap(pathToImageFile);
var exif = new EXIFextractor(ref bmp, "n"); // get source from http://www.codeproject.com/KB/graphics/exifextractor.aspx?fid=207371
if (exif["Orientation"] != null)
{
RotateFlipType flip = OrientationToFlipType(exif["Orientation"].ToString());
if (flip != RotateFlipType.RotateNoneFlipNone) // don't flip of orientation is correct
{
bmp.RotateFlip(flip);
bmp.Save(pathToImageFile, ImageFormat.Jpeg);
}
// Match the orientation code to the correct rotation:
private static RotateFlipType OrientationToFlipType(string orientation)
{
switch (int.Parse(orientation))
{
case 1:
return RotateFlipType.RotateNoneFlipNone;
case 2:
return RotateFlipType.RotateNoneFlipX;
case 3:
return RotateFlipType.Rotate180FlipNone;
case 4:
return RotateFlipType.Rotate180FlipX; …Run Code Online (Sandbox Code Playgroud)