C# 图像未在正确的位置绘制
我还不明白这个c代码的输出 原始图像未放置在正确的位置。它应该位于C# 图像未在正确的位置绘制,c#,.net,winforms,image-processing,gdi+,C#,.net,Winforms,Image Processing,Gdi+,我还不明白这个c代码的输出 原始图像未放置在正确的位置。它应该位于(0,0)。 另外,我需要一个黑色的背景 那么,到底发生了什么以及如何纠正这一点呢?我不完全清楚您实际需要做什么。但无论如何,这里有一个WPF友好的示例,说明如何在另一个图像中的特定位置绘制图像 注意:如果您只想以不同的大小显示图像和/或在图像周围加上黑色边框,则有更简单的方法,无需创建第二个图像,例如仅将图像放置在已具有所需边框样式的面板中 请注意,我使用的是System.Windows.Media命名空间中的类,因为WPF使用
(0,0)
。
另外,我需要一个黑色的背景
那么,到底发生了什么以及如何纠正这一点呢?我不完全清楚您实际需要做什么。但无论如何,这里有一个WPF友好的示例,说明如何在另一个图像中的特定位置绘制图像 注意:如果您只想以不同的大小显示图像和/或在图像周围加上黑色边框,则有更简单的方法,无需创建第二个图像,例如仅将图像放置在已具有所需边框样式的面板中 请注意,我使用的是System.Windows.Media命名空间中的类,因为WPF使用的是这些类。这些类不容易与System.Drawing命名空间中的旧类混合(有些类名冲突,Microsoft的.Net framework缺少在这些类型之间转换对象的内置方法),因此通常只需决定是否使用一组或其他绘图工具。我想您一直在尝试使用System.Drawing。每种方法都有各自的优缺点,在这里要花很长时间来解释
Bitmap image = ReadBitmap("image.png");
Bitmap imageCopy = new Bitmap(image);
Bitmap canvas = new Bitmap(imageCopy.Width+100, imageCopy.Height);
// From this bitmap, the graphics can be obtained, because it has the right PixelFormat
using(Graphics g = Graphics.FromImage(canvas))
{
// Draw the original bitmap onto the graphics of the new bitmap
g.DrawImage(image, 0, 0);
}
// Use tempBitmap as you would have used originalBmp
InputPictureBox.Image = image;
OutputPictureBox.Image = canvas;
您正在加载图像,然后使用以下命令创建此源的副本:
Bitmap Bitmap=新位图()代码>
以这种方式创建图像副本时,会牺牲/更改某些细节:
:如果未另行指定,分辨率将设置为UI分辨率。96 Dpi,作为标准;不同的屏幕分辨率和缩放比例可能会有所不同。正在使用的系统也会影响此值(Windows 7和Windows 10可能会提供不同的值)
:如果未直接从图像源复制或明确指定,PixelFormat
将设置为PixelFormat.Format32bppArgb
从你刚才所说的,你可能想要这样的东西:
// using System.Windows.Media;
// using System.Windows.Media.Imaging;
private void DrawTwoImages()
{
// For InputPictureBox
var file = new Uri("C:\\image.png");
var inputImage = new BitmapImage(file);
// If your image is stored in a Resource Dictionary, instead use:
// var inputImage = (BitmapImage) Resources["image.png"];
InputPicture.Source = inputImage;
// imageCopy isn't actually needed for this example.
// But since you had it in yours, here is how it's done, anyway.
var imageCopy = inputImage.Clone();
// Parameters for setting up our output picture
int leftMargin = 50;
int topMargin = 5;
int rightMargin = 50;
int bottomMargin = 5;
int width = inputImage.PixelWidth + leftMargin + rightMargin;
int height = inputImage.PixelHeight + topMargin + bottomMargin;
var backgroundColor = Brushes.Black;
var borderColor = (Pen) null;
// Use a DrawingVisual and DrawingContext for drawing
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
// Draw the black background
dc.DrawRectangle(backgroundColor, borderColor, new Rect(0, 0, width, height));
// Copy input image onto output image at desired position
dc.DrawImage(inputImage, new Rect(leftMargin, topMargin,
inputImage.PixelWidth, inputImage.PixelHeight));
}
// For displaying output image
var rtb = new RenderTargetBitmap( width, height, 96, 96, PixelFormats.Pbgra32 );
rtb.Render(dv);
OutputPicture.Source = rtb;
}
这就是结果:
(上/下框黑色实际上是Picturebox
背景色)
当原始图像Dpi分辨率与使用新位图()创建图像副本时使用的基本Dpi分辨率不同时,您的结果可能与预期不同。
在同一场景中,150、96和72 Dpi的源图像会发生这种情况:
另一个重要细节是图像对象的性质。
当你创建一个时,你必须考虑它的价值;显式地调用Dispose
方法,或隐式地将映像构造函数封装在一个函数中。
另外,也可能不要指定直接从文件流加载的图像对象
GDI+将锁定该文件,您将无法复制、移动或删除它。
使用该文件,与图像关联的所有资源也将被锁定。
使用new Bitmap()
(如果您不关心上述详细信息),或使用,这将保留图像Dpi分辨率
和PixelFormat
此代码将源图像复制到新的图像容器中。目标容器大小在其100像素的X维度中增加。然后将源图像复制到新容器中。因为只指定了原点,所以源图像会扭曲以适合其容器。源图像未被触及。这两个图像都被传递到PictureBox。图像在控件上的显示方式取决于控件大小模式(缩放、拉伸、自动调整大小…)。我需要一个黑色背景:在图像副本上?如果是这样,则在绘制画布时已完全填充画布)。此外,没有任何图像被释放,并且源图像将被GDI+锁定(在图像(及其流)被Disposed()之前,您不能触摸基础文件)
。你应该解释一下预期的结果。可能的话,在图像的左右两侧创建一个更大的画布,作为图像的黑色边框?@Jimi因为只指定了原点,所以源图像会被扭曲以适合它的容器。不。图像是以其原始大小绘制的。如果他有sp,则会发生扭曲指定的宽度和高度g.DrawImage(图像,0,0,canvas.width,canvas.height)您可以放大图片框。将其更改为正常。@γηρρσκωδ′αεπολλλλδδασκμε是的,可能扭曲不是选择的词。放大(某种扭曲)。但也应该裁剪(Y维度)。
using (Bitmap imageSource = (Bitmap)Image.FromFile(@"[SomeImageOfLena]"))
using (Bitmap imageCopy = new Bitmap(imageSource.Width + 100, imageSource.Height, imageSource.PixelFormat))
{
imageCopy.SetResolution(imageSource.HorizontalResolution, imageSource.VerticalResolution);
using (Graphics g = Graphics.FromImage(imageCopy))
{
g.Clear(Color.Black);
g.CompositingMode = CompositingMode.SourceCopy;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(imageSource, (imageCopy.Width - imageSource.Width) / 2, 0);
pictureBox1.Image = (Image)imageSource.Clone();
pictureBox2.Image = (Image)imageCopy.Clone();
}
}