【问题标题】:Set child Image Background when Parent Image is Zoomed缩放父图像时设置子图像背景
【发布时间】:2013-10-09 18:38:18
【问题描述】:

我有一个图像控件,可以在其中放大和缩小所选图像。

用户可以在运行时对图像进行一些控制。放置控件后,如果用户放大图像,则控件不会缩放,而是相对于它们在图像中的位置移动。所以控件在图像上的位置保持不变,只是图像会被缩放。

说了这么多,要求是导出完整的图像以及用户添加的控件。

我已经用下面的代码实现了这个功能:

Bitmap bmpCopy = new Bitmap(picEditIsdDiagram.Image);

Graphics canvas = Graphics.FromImage(bmpCopy);
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
try
{
    foreach (Control MeasurementSymbol in picEditIsdDiagram.Controls)
    {
        if (MeasurementSymbol is DevExpress.XtraEditors.HScrollBar || MeasurementSymbol is DevExpress.XtraEditors.VScrollBar)
        {
            continue;
        }

        Bitmap bmpControl = new Bitmap(MeasurementSymbol.Width, MeasurementSymbol.Height);
        MeasurementSymbol.DrawToBitmap(bmpControl, new Rectangle(Point.Empty, bmpControl.Size));
        bmpControl.MakeTransparent(Color.Transparent);

        canvas.DrawImage(
                            bmpCopy,
                            new Rectangle(0, 0, bmpCopy.Width, bmpCopy.Height),
                            new Rectangle(0, 0, bmpCopy.Width, bmpCopy.Height),
                            GraphicsUnit.Pixel
                        );

        canvas.DrawImage(bmpControl, ((UcMeasurementSymbol)MeasurementSymbol).PointInImage);
        canvas.Save();
    }

    FolderBrowserDialog save = new FolderBrowserDialog();

    save.RootFolder = Environment.SpecialFolder.Desktop;

    if (save.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
        int count = 1;

        string destinationPath = save.SelectedPath + "\\" + IsdDiagram.Isd.Name + " - " + IsdDiagram.Name + ".Jpeg";

        while (File.Exists(destinationPath))
        {
            destinationPath = save.SelectedPath + "\\" + IsdDiagram.Isd.Name + " - " + IsdDiagram.Name + " [" + count++.ToString() + "].Jpeg";
        }

        bmpCopy.Save(destinationPath, ImageFormat.Jpeg);
        SERVICE.NMessageBox.Show("Complete Diagram saved successfully in Jpeg format", "Image Saved", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}
catch (Exception ex)
{
    SERVICE.NMessageBox.Show("Error exporting complete Diagram. Error :" + ex.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

现在,当我缩放图像,然后单击“导出图表”按钮时,就会出现问题。 缩放后仅显示图像的特定区域。因此,控件的背景(即控件的可见区域之外)图像已更改,并且与图像不同。

我附上图片以作进一步说明:

缩放前的图像:

缩放后的图像:

所以在上面的图片中,你可以看到Control图片的背景并不像预期的那样。

即使在应用 ZOOM 之后,谁能帮我获得正确的背景?

【问题讨论】:

  • 只对控件进行屏幕捕获(其中包含控件)会不会太便宜?
  • @noelicus:我没明白你的意思。
  • 我理解你的问题是:导出的图像与查看的图像(控件)不同。如果是这样,那么对主控件进行屏幕截图将是一种更简单的方法。
  • 主控件的截屏只会导出图片的可见区域(放大后),不会导出完整的图片。
  • 好的。所以你的问题是你在上面绘制的控件不透明?你只是说“不是按照图片”! - 真正的问题是什么?

标签: c# winforms image graphics


【解决方案1】:
    MeasurementSymbol.DrawToBitmap(bmpControl, new Rectangle(Point.Empty, bmpControl.Size));
    bmpControl.MakeTransparent(Color.Transparent);

很难回答的问题是为什么这段代码会生成一个完全透明的图像。换句话说,上面的图像是奇怪的图像,下面的图像是正常的。控件,如 bmpControl,不使用 Color.Transparent 绘制自身。话又说回来,我们看不出这可能是一种什么样的控制。

您需要停止使用控件来存储这些图像。而是将它们存储在位图中。确保您不依赖控件的善意以您希望的方式绘制自己的唯一方法。并确保您传递给 MakeTransparent 的颜色实际上与位图的背景颜色相匹配。如果它已经是透明的,使用像PNG这样支持透明的图像格式,那么根本不要调用MakeTransparent()。

【讨论】:

  • 小图像是一个UserControl,它有一个PictureBox 和一个Label 控件。在运行时,用户可以将 UserControl 移动到图像上,因此我必须将其保留为控件。重新考虑图像格式,它将始终为 JPEG。
  • JPEG 不支持透明度。由于压缩伪影,MakeTransparent() 也不能很好地工作。不要使用JPEG。否则,飞机图像并不重要。
  • 好的...我在之前的评论中遗漏了一些东西。用户可以上传 JPEG 格式的图像,并将其保存在数据库中。之后,在另一个页面上,从数据库中检索该图像后会显示该图像。我不知道这是否重要。但正如您所见,在第一张图片中它运行良好。
  • 好的...说了这么多之后,我删除了那段代码,但这不会影响我的任何图像。所以我可以删除那段代码。没有问题。但问题依然存在。
  • 我想我必须重复一遍,除非你停止使用 DrawToBitmap(),否则情况不会好转。