我想绘制一个自定义线帽 - 一个半径为 r 的等边三角形。显然我不能:
Dim triangleSide As Single = CSng(3 * r / Math.Sqrt(3))
Dim triangleHeight As Single = CSng(3 * r / 2)
path = New GraphicsPath()
Dim points() As PointF = New PointF() { _
New PointF(-triangleSide / 2, 0), _
New PointF(triangleSide / 2, 0), _
New PointF(0, triangleHeight) }
path.AddLines(points)
' Not Implemented Exception, Was is Das? '
_HlpCap = New CustomLineCap(path, Nothing)
Run Code Online (Sandbox Code Playgroud)
我有什么问题还是只是一个框架错误?
编辑:
Mark Cidade 评论后,我尝试使用(Nothing, path)它并有所帮助,但我需要填充三角形,而不是仅将其描边......
如果我使用此方法创建图像,然后尝试删除/修改图像文件,我会收到错误,因为有一个流仍在使用该文件。
如何删除或处置此流以便我可以处理该文件?
背景
我正在开发一个应用程序,该应用程序应该以相同的方式在从 XP 开始的每个 Windows 平台上运行。通过 .NET 框架,这在大多数情况下都非常容易。该应用程序可在各种触摸表面上运行。该应用程序面向 .Net 3.0,但如果由于某种原因我应该迁移到 .Net 3.5,我可以这样做。我无法使用4.0。
该应用程序通过 System.Drawing 命名空间大量使用 GDI+。现在,我了解到 GDI+ 要么根本没有硬件加速,要么只在极少数显卡中加速,所以我预计会出现一些性能问题。然而,这个问题很明显,并且使应用程序的可用性显着降低。如果可以通过简单的修复来避免的话,我宁愿不将整个应用程序重写为目标 DirectX 或 OpenGL。
问题
我们最近在其中一张触摸桌上安装了 Windows 7 64 位。这是该应用程序首次在 Windows 7 64 位计算机上运行。无论如何,一次使用多个手指在设备上进行任何绘图(特别是 DrawLine)都会导致严重的延迟。这种延迟在 32 位 Windows XP 或 32 位 Windows 7 上并不明显,因此我认为它可能特定于 64 位 Windows 7(我没有 64 位 XP 机器来测试)。
该应用程序还被迫作为 32 位应用程序运行,因为其中一个 .dll 文件只有 32 位库可用于编译它。我在某处读到,在 64 位系统上强制进程进入 32 位模式可能会导致性能问题,但是当我升级我们正在使用的 SDK 并制作 64 位特定的 .dll 和应用程序时,问题仍然存在。
我在 StackOverflow 的另一个帖子中读到,在 GDI+ 方面,32 位和 64 位应用程序之间应该没有区别。这里的情况似乎并非如此。
那么问题来了:你们知道为什么 Windows 32 …
任何 PixelFormat 都可以与任何 ImageFormat 一起使用吗?
我正在使用 System.Drawing.Bitmap 进行一些图像处理。当我创建位图时,我被要求提供 PixelFormat;当我保存位图时,我被要求提供一个 ImageFormat。这里有任何无效的组合吗?
为了帮助回答,这里是 PixelFormats 和 ImageFormats 的列表:
像素格式(MSDN - System.Drawing.PixelFormat):
Gdi*
Alpha*
PAlpha*
Extended*
Canonical*
Undefined*
DontCare*
Max*
Format1bppIndexed
Format4bppIndexed
Format8bppIndexed
Format16bppGrayScale**
Format16bppRgb555
Format16bppRgb565
Format16bppArgb1555
Format24bppRgb
Format32bppRgb
Format32bppArgb
Format32bppPArgb
Format48bppRgb
Format64bppArgb
Format64bppPArgb
Run Code Online (Sandbox Code Playgroud)
* - 传递给 new Bitmap() 时导致 ArgumentException
** - 不适用于任何 ImageFormat
ImageFormats ( MSDN - System.Drawing.ImageFormat ):
Bmp
Emf
Exif
Gif
Icon
Jpeg
MemoryBmp
Png
Tiff
Wmf
Run Code Online (Sandbox Code Playgroud)
编辑 1:使用 PixelFormats 更新 PixelFormat 列表,在创建位图时会导致异常。
编辑 2:通过我自己的一些测试,似乎 PixelFormat“ …
我有工作的 Windows 窗体应用程序,它从网站获取 jpeg 图像并将其显示在图像控件中。但是,当我尝试使用 Image.Save 函数将图像保存到文件系统时,它会创建文件但将其留空。不知道我做错了什么......
在下面,DownloadData() 成功检索了包含图像的字节数组。
byte[] imageData = DownloadData();
MemoryStream stream = new MemoryStream(imageData);
Image img = Image.FromStream(stream);
stream.Close();
picMain.Image = img;
string fname = @"C:\Users\mikec1\Pictures\Construction\Construction_" + Now.ToString("yyyyMMdd") + "_" + Now.ToString("HHmmss") + ".jpg";
picMain.Image.Save(fname, System.Drawing.Imaging.ImageFormat.Jpeg);
Run Code Online (Sandbox Code Playgroud)
如果我从 img 对象执行 Save ,我会得到相同的结果。
事实上,应用程序在执行最后一行时终止,而没有明显地抛出异常。
我最近将 ASP.NET MVC 应用程序从 ASP.NET 升级到 ASP.NET Core。
在我的控制器操作中,我有一段代码依赖 System.Drawing 创建个人资料图片
using (FileStream stream = new FileStream(HttpContext.Server.MapPath($"~/Content/UserFiles/{AuthenticatedUser.Id.ToString()}.jpg"), FileMode.OpenOrCreate))
{
Image image = Image.FromStream(model.DisplayPicture.InputStream);
image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
}
Run Code Online (Sandbox Code Playgroud)
图像数据作为 Base64 编码图像发布到服务器
data:image/png;base64,....
Run Code Online (Sandbox Code Playgroud)
由于System.Drawing.NET Core 中没有,是否还有其他库可以实现这一点?
我有一个 PNG 文件,文件属性证明它具有 8 位颜色深度:
是的,当我打开文件时
var filePath = "00050-w600.png";
var bitmap = new Bitmap(filePath);
Console.WriteLine(bitmap.PixelFormat);
Run Code Online (Sandbox Code Playgroud)
我明白了Format32bppArgb。我还查看了PropertyIdList和PropertyItems属性,但没有看到任何明显的东西。
那么如何从 PNG 中提取位深度呢?
PS 没有框架方法似乎工作。 System.Windows.Media.Imaging.BitmapSource可能有效,但仅适用于 WPF 和 .NET Core 3。我需要它用于 .NET 4.x 和 .NET Core 2.x。
PPS 我只需要知道 PNG 是否是 8 位,所以我写了一个确定的方法来检查是否有人需要它 - 应该在任何框架中工作。
public static bool IsPng8BitColorDepth(string filePath)
{
const int COLOR_TYPE_BITS_8 = 3;
const int COLOR_DEPTH_8 = 8;
int startReadPosition = 24;
int colorDepthPositionOffset = 0;
int colorTypePositionOffset = 1;
try
{
using …Run Code Online (Sandbox Code Playgroud) 对于 .NET 7,System.Common.Drawing 不再在非 Windows 平台上使用。我喜欢将我的应用程序迁移到 Microsoft.Maui.Graphics(正如 Microsoft 在 .NET 6/7 的重大更改页面上建议的那样)。\n它们支持 Windows 上的 GDI+,这非常好,因为它可以最大限度地减少迁移的副作用。在 Linux 或 MacOS 上,我可以使用 SkiaImage 实现。
\n然而它\xe2\x80\x99s不清楚如何实现这一点。目前的文档非常有限。从源代码中我找到了IImageLoaderServiceIImage 和几个实现。
根据平台,我会注册权利IImageLoaderService,一切都应该正常。
if (RuntimeInformation.IsOsPlatform(OsPlatform.Windows) \n{ \n services.AddSingleton<IImageLoaderService, GDIImageLoaderService>()\n} \nelse \n{\nservices.AddSingleton<IImageLoaderService, SkiaImageLoaderService>() \n}\nRun Code Online (Sandbox Code Playgroud)\n理论上到目前为止。但是,在引用Microsoft.Maui.GraphicsNuget 后,仅IImageLoaderService可用。
如何GDIImageLoaderService在 Windows 上注册(或如何调用服务以使用 gdi+)?
在创建包含数千个形状的绘图应用程序或模拟时,建议使用从Visual派生的类(如DrawingVisual)而不是由于性能下降而从Shape派生的类.
我想知道性能下降了多少,并且由于派生类层次结构中的FrameworkElement类而占大多数?除了使用Visual而不是Shape之外应该决定的阈值是多少?在链中丢失UIElement和FrameworkElement的优缺点是什么?
使用System.Drawing.Font,是否可以更改字母间距,就像可以更改字体大小一样?
我正在寻找增加字母间距以适合特定宽度的方法。
如果无法做到这一点,是否有其他替代方法可获得理想的效果?例如,是否有一种简单的方法来制作多个适合我特定宽度的图形?