Tag: gdi +

Windows /.NET的System.Drawing.Save(Stream,ImageFormat)中的错误。 腐败的PNG产生了

在某些非常特殊的情况下,System.Drawing.Save(Stream,Imageformat)会创建损坏的PNG图像。 有没有办法避免它,这样: 我不需要使用第三方库,而且 我不需要检查PNG字节以了解我是否需要“修复”某些东西? 重现步骤 创建一个System.Drawing.BitMap 向图像添加内容,以便产生非常特定的PNG文件大小(“何时发生”) 调用Save(Stream,Imageformat) – 选择PNG格式 问题是什么? 问题是最后一个图像数据后的IDAT块不正确。 它包含NO数据,但长度字节为00 00 ff f4。 可以使用https://github.com/jsummers/tweakpng检测它。 我们注意到Linux上的图像库(不确定哪些)无法处理这些错误。 据我们所见,在Windows中,这个错误被忽略了,你不会发现任何问题。 什么时候发生? 这取决于PNG文件的大小。 如果生成的PNG文件大小(以字节为单位)为0x1001C + n * 0x10000且n为0,1,2,3,4且可能更大,则只会出现此问题。 它是可重复的 可以调整步骤2以产生特定的PNG文件大小(例如,在其他空的BitMap中为不同数量的像素着色)。 当尺寸如上所述时,错误一直发生。 代码重现 在干净的控制台应用程序中替换Program.cs的内容。 运行程序时,它将尝试创建具有指定大小的PNG并将其另存为“construct.png”。 另外:第二个PNG保存为“constructReExport.png”:这是通过加载第一个并再次保存来创建的。 我想我记得这是一个潜在的解决方法,但是当我现在运行它时,第二个文件包含相同的错误… using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; namespace CreateCorruptPng { class Program { static void Main(string[] args) { // Choose […]

如何使用两个PointF创建一个RectangleF?

我创建了两个点,就像一条线。 我想将其转换为矩形。 我该怎么办? 例如,这是我画线的方式。 但我希望它是一个Rectangle private PointF start, end; protected override void OnMouseDown(MouseEventArgs e) { start.X = eX; start.Y = eY; } protected override void OnMouseUp(MouseEventArgs e) { end.X = eX; end.Y = eY; Invalidate(); }

在C#/ GDI +中从Format8bppIndexed转换为Format24bppRgb

好吧,我有一个以8位索引格式从外部应用程序传来的图像。 我需要将此图像转换为完全相同大小的24位格式。 我已经尝试创建一个相同大小和类型为Format24bppRgb的新Bitmap,然后使用Graphics对象在它上面绘制8位图像,然后将其保存为Bmp。 这种方法不会出错,但是当我打开生成的图像时,BMP标题具有各种质朴的值。 高度和宽度都是巨大的,此外,还有压缩标志和其他一些有趣(和大)的值。 不幸的是,我的特殊要求是将此文件传递给特定的打印机驱动程序,该驱动程序需要具有特定标头值的24位图像(我试图通过GDI +实现) 有人知道将索引文件“上转换”为非索引的24位文件的示例吗? 如果不是一个例子,我应该从哪个路径开始编写自己的路径? -Kevin Grossnicklaus kvgros@sseinc.com

LinearGradientBrush无法正确呈现

请考虑标准System.Windows.Forms.Form的以下代码 protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Rectangle test = new Rectangle(50, 50, 100, 100); using (LinearGradientBrush brush = new LinearGradientBrush(test, Color.Red, Color.Blue, 0f)) { e.Graphics.DrawRectangle(new Pen(brush, 8), test); } } 它产生了这个结果: 为什么红线和蓝线显示的顺序不正确,如何修复?

什么可能导致双缓冲杀死我的应用程序?

我有一些使用GDI +绘制到屏幕的自定义(winforms)组件。 为了防止重绘闪烁,我决定启用双缓冲,所以我在构造函数中添加了一行: public ColourWheel() { InitializeComponent(); this.DoubleBuffered = true; } 哪个适用于此组件(ColourWheel)。 当我将同一行添加到我的另外两个(结构相似的)组件的构造函数中时,我会得到一些奇怪的症状: 当我尝试运行组件打开的表单时,我在Application.Run(new Form());上获得了一个Argument Exception Application.Run(new Form()); 。 如果我切换到设计模式,我得到一个错误,关于具有未处理的exception的组件与参数。 我是否对其中一个或全部进行双缓冲似乎并不重要,它仍然适用于ColourWheel,但不适用于其他人。 为了记录,我还尝试了一些其他双 缓冲技术。 什么可能导致双缓冲在一个组件上工作,而不是其他组件? 编辑:这是运行时症状的exception细节: System.ArgumentException未处理Message = Parameter无效。 Source = System.Drawing StackTrace:System.Drawing.Graphics.GetHdc(),位于System.Windows.Forms.Control的System.Drawing.BufferedGraphics.Render()的System.Drawing.BufferedGraphics.RenderInternal(HandleRef refTargetDC,BufferedGraphics缓冲区)中。系统中System.Windows.Forms.UserControl.WndProc(Message&m)的System.Windows.Forms.ScrollableControl.WndProc(Message&m)处的System.Windows.Forms.Control.WndProc(Message&m)处的.WmPaint(Message&m) .Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&m)at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&m)at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam, IntPtr lparam)在System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&msg)处于System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID,Int32 reason,Int32 pvLoopData)at at System.Windows.Forms.Application.ThreadContext.Run MessageLoopInner(Int32 reason,ApplicationContext context),位于TestForm.Program.Main()的System.Windows.Forms.Application.Run(Form mainForm)的System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason,ApplicationContext context)中D:\ Documents and Settings […]

如何从原始区域填充线性渐变画笔区域?

我正在使用LinearGradient画笔填充区域,我使用起点和终点Color创建了linearGradient画笔。 Rectangle linearGradientregion= new Rectangl(20,-50,30,30); LinearGradientBrush linearGradientBrush = new LinearGradientBrush(new PointF(20, -20), new PointF(50, -50), Color.Green, Color.Red); Rectangle pathRegion= new Rectangl(-50,-25,50,50); GraphicsPath path = new GraphicsPath(); path.AddRectangle(pathRegion); graphics.FillPath(linearGradientBrush, path); 并且区域大小大于linearGradientBrush边界区域。 现在我想知道如何使用linearGradientBrush边界区域仅使用linearGradientBrush来填充区域,并使用填充了另一种颜色的区域中的剩余区域。 下图是期望输出。 http://sofzh.miximages.com/c%23/B4CHB.png 但我得到的结果是这样的 http://sofzh.miximages.com/c%23/Pxwiw.png 在第一张图像中,填充绿色的圆圈超出了线性渐变画笔的界限。 在第二幅图像中,渐变画笔再次填充该区域。 我想在线性渐变画笔的终点处停止渐变画笔填充,并用另一种颜色填充剩余区域。 提前致谢, Parthi

从自定义PictureBox控件翻译不同大小的图像的点(X,Y)

我必须批量处理几个图像。我必须在特定点(X,Y)放置一些文本。有一个从图片框派生的自定义控件,允许用户拖动文本并将其放在所需的位置。 有两种类型的图像,我以不同的方式设置PictureBoxSizeMode 垂直图像 我设置> PictureBoxSizeMode.Zoom; 横 对于填充PictureBox的水平图像,我设置了> PictureBoxSizeMode.StretchImage 用户可以通过在该图片框控件上拖动文本来选择放置文本的位置。将原始图像调整为控件大小(对于水平图像),并且用户将文本拖动到该图像上。 基于Picturebox的SizeMode,使用以下代码将所选点转换为原始图像内的点 if (sizemode == 1) { transpoint = TranslateStretchImageMousePosition(new Point(eX – 20, eY -20)); } else if (sizemode == 2) { transpoint = TranslateZoomMousePosition(new Point(eX – 20, eY – 20)); } public Point TranslateStretchImageMousePosition(Point coordinates) { // test to make sure our image is not null […]

如何在旋转canvas上精确绘制橡皮筋选择矩形?

这是在canvas上绘制的橡皮筋选择矩形。 我的问题是,如果canvas内容没有旋转,很容易获得正确的矩形大小。 但是一旦旋转,矩形就不再与光标一起变大。 我需要橡皮筋与屏幕保持平行 var dragPt = new PointF(e.Position.X – G.ReferenceOffset.X, e.Position.Y – G.ReferenceOffset.Y); var rotation = ADEEnvironment.RotateAngle; var width = (dragPt.X – pressPt.X); var height = (dragPt.Y – pressPt.Y); 代码非常简单。 我在鼠标按下时捕获鼠标的位置:pressPt。 在鼠标移动事件中,我得到当前鼠标位置dragPt并计算橡皮筋矩形的宽度和高度,并使用这些值创建一个矩形,其原点在pressPt上。 如果canvas的相机没有旋转,这可以正常工作。 当我旋转显示器时,我需要橡皮筋与屏幕保持对齐而不是绘制它的canvas。 它我只是留下它旋转绘制的橡皮筋。 如果我旋转橡皮筋矩形使其返回到与屏幕对齐,则矩形不再正确resize。 所以在经历了很多混乱之后我尝试了一些三角函数: var width = (float)((dragPt.X – pressPt.X) / Math.Cos(rotation)); var height = (float)((dragPt.Y – pressPt.Y) / Math.Cos(rotation)); 考虑到旋转角度可以是0> […]

从头开始编写/绘制我自己的ListBox / ListView控件

我将如何找到如何制作Windows窗体Control ? 我想从头开始创建一个Control 。 最好是ListBox甚至更好的ListView Control ,但我不知道从哪里开始。 我过去遇到的一些建议是: 使用Panel Control并使用适当的样式动态添加Label控件; 扩展或子类化ListView / ListBox Control ,并将OwnerDraw设置为true ,并在OnPaint事件中执行自定义绘图。 但我想要更多的控制权。 我不只是想要一个ListView Control ,我也不想使用第三方控件(不管有多好[Object ListView]是1.我想要自己的 ListView Control 。我不在乎它有多难是,但这可能在Windows窗体中?我应该从哪里开始? 我需要使用GDI / GDI+来绘制所有内容吗? 我会从一个空的Panel Control ,然后使用System.Drawing命名空间手动绘制每个List Item吗?

使用自定义颜色替换/重绘TextBox 3D边框

情景 在WinForms中 ,当BorderStyle属性设置为Flat , None或Fixed3D时,我已经将文本 Fixed3D分类为使用纯色绘制我自己的边框。 问题 当我的TextBox属性设置为Fixed3D ,当我尝试使用颜色绘制边框时,表面上的边框未正确绘制: 您在图像中看到的是一个缩放的TextBox,其中包含: BackColor =黑色 BorderStyle = Fixed3D(白色的东西) 红色的是我的边界意图。 题 在C#或VB.Net中,我如何替换/重绘3D边框来做我想要的?,我的意思是替换/隐藏/重绘上面图像的白色边框。 码 这是我在OnPaint方法上尝试过的: Using g As Graphics = Graphics.FromHwnd(Me.Handle) ‘ Dim rect As Rectangle = New Rectangle(0, 0, Me.Width, Me.Height) ‘ Dim pen As New Pen(Color.Black, 2) ‘ pen.Alignment = PenAlignment.Inset ‘ g.DrawRectangle(pen, rect) ControlPaint.DrawBorder(Graphics.FromHwnd(Me.Handle), Me.ClientRectangle, Me.borderColor1, ButtonBorderStyle.Solid) […]