Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 图像未在正确的位置绘制_C#_.net_Winforms_Image Processing_Gdi+ - Fatal编程技术网

C# 图像未在正确的位置绘制

C# 图像未在正确的位置绘制,c#,.net,winforms,image-processing,gdi+,C#,.net,Winforms,Image Processing,Gdi+,我还不明白这个c代码的输出 原始图像未放置在正确的位置。它应该位于(0,0)。 另外,我需要一个黑色的背景 那么,到底发生了什么以及如何纠正这一点呢?我不完全清楚您实际需要做什么。但无论如何,这里有一个WPF友好的示例,说明如何在另一个图像中的特定位置绘制图像 注意:如果您只想以不同的大小显示图像和/或在图像周围加上黑色边框,则有更简单的方法,无需创建第二个图像,例如仅将图像放置在已具有所需边框样式的面板中 请注意,我使用的是System.Windows.Media命名空间中的类,因为WPF使用

我还不明白这个c代码的输出

原始图像未放置在正确的位置。它应该位于
(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();
    }
}