【问题标题】:What properties of an image might cause sizing problems?图像的哪些属性可能会导致尺寸问题?
【发布时间】:2011-01-20 23:04:49
【问题描述】:

作为我 ongoing quest 为实验生成刺激的一部分,我遇到了一个奇怪的问题。

这次想要的结果是通过将图像分成大小相等的片段然后随机交换这些片段来“洗牌”图像。这在最初的测试中运行良好,我很快就忘记了这个程序。然而,当我的同事用她的图像进行尝试时,这些片段突然变得比它们应该的要小。

为了说明问题,我用阴影画笔填充了每个分段矩形:

图像对 A 显示了我从测试图像(从 facebook 下载)的初始结果。图像对 B 显示了应用于我同事测试图像的相同操作;请注意,阴影区域之间有间隙。在我在 GIMP 中修改原始图像并重新保存后,第三对图像显示相同的效果。 (我最初这样做是为了看看方向是否有任何影响 - 它没有。)

在我看来,从 GIMP 导出图像的过程会影响图像的某些属性,从而导致尺寸被错误地解释。有什么方法可以检测和纠正这个问题吗?


我的代码(为您的理智而编辑):

this.original = Image.FromFile(this.filename);
Image wholeImage = (Image)this.original.Clone();

int segwidth = (int)Math.Floor((double)(this.original.Width / segsX));
int segheight = (int)Math.Floor((double)(this.original.Height / segsY));

int segsCount = segsX * segsY;
Image[] segments = new Image[segsCount];

for (i = 0; i < segsCount; i++)
{
    x = (i % segsX);
    y = (int)Math.Floor((double)(i / segsX));
    segments[i] = Crop(wholeImage, new Rectangle(x * segwidth, y * segheight, segwidth, segheight), (i%2>0));
}

// Call to an array shuffling helper class

using (Graphics g = Graphics.FromImage(wholeImage))
{
    for (j = 0; j < segsCount; j++)
    {
        x = (j % segsX);
        y = (int)Math.Floor((double)(j / segsX));
        insertPoint = new Point(x * segwidth, y * segheight);
        g.DrawImage(segments[j], insertPoint);
    }
}

wholeImage.Save(this.targetfolder + Path.DirectorySeparatorChar + aggr_filename, ImageFormat.Png);

// The cropping function (including the hatch generation, which would be commented out when no longer needed)
static private Image Crop(Image wholeImage, Rectangle cropArea, Boolean odd = true)
{
    Bitmap cropped = new Bitmap(cropArea.Width, cropArea.Height);
    Rectangle rect = new Rectangle(0, 0, cropArea.Width, cropArea.Height);
    System.Drawing.Drawing2D.HatchBrush brush;
    if (odd)
    {
        brush = new System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.Plaid, Color.Red, Color.Blue);
    }
    else
    {
        brush = new System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.Plaid, Color.Beige, Color.CadetBlue);
    }
    using(Graphics g = Graphics.FromImage(cropped))
    {
        g.DrawImage(wholeImage, rect, cropArea, GraphicsUnit.Pixel);
        g.FillRectangle(brush, rect);
    }
    return cropped as Image;
}

【问题讨论】:

  • 对 Image 实例使用 using(this.original = Image.FromFile(this.filename)){...}。这不会解决问题,否则会导致内存泄漏。
  • 啊,谢谢CaptainPlanet!仍然不是 C# 原生... :)

标签: c# graphics image-processing


【解决方案1】:

--根据 OP 的要求添加为答案--

只是为了它,我将它移植到 php 并且它可以按您期望的那样工作(侧面的边距,而不是单个图块周围的边距。但是,这将我带到了 drawimage(image,point) 的 msdn 页面, 这似乎是根据显示设备的 dpi 而不是固定的像素尺寸来渲染 sepcified 图像。您的裁剪功能使用 rect 并指定每个像素的测量值,但您的重绘例程使用不同的方法.尝试使用 drawimage您在裁剪函数中用于图像重建的方法

【讨论】:

    【解决方案2】:

    可能还有更多,但我没有注意到在图像大小不能被分段大小整除的情况下处理额外像素的机制。你的测试用例有没有可能都是完美契合的?

    假设一个 100 x 100 的图像,10 个片段:

    100/10 = 10; 10 x 10 = 100 像素。

    假设一个 100 x 100 的图像,13 段:

    100/13 = 7; 13 * 7 = 91 像素。

    【讨论】:

    • 确实这个处理不妥,但是效果不同。您可以在图像对 A 上看到,由于不精确的拟合,右侧和底部边缘有一个未填充的边距。 (还是)感谢你的建议。 :)
    • 我认为边距来自您使用所需的段数 (segX) 来计算原点。您可能应该使用平铺宽度(在我的 13 示例中:7px),并且您需要为最后一行/列添加一个特殊情况,这将是不同的大小。
    • 只是为了它,我将它移植到 php 并且它可以按您期望的那样工作(侧面的边距,而不是单个图块周围的边距。但是,这将我带到了 drawimage 的 msdn 页面(图像,点),它似乎根据显示设备的 dpi 渲染 sepcified 图像,而不是固定的像素尺寸。您的裁剪功能使用 rect 并指定每个像素的测量值,但您的重绘例程使用不同的方法. 尝试使用您在crop函数中使用的drawimage方法进行图像重建
    • 很好地捕捉到了horatio - 在第二个drawimage函数中指定像素有效。想发布另一个答案,以便我可以将其标记为已接受?
    猜你喜欢
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    • 1970-01-01
    • 1970-01-01
    • 2017-05-05
    • 1970-01-01
    相关资源
    最近更新 更多