What properties of an image might cause sizing problems?
As part of my ongoing quest to generate stimuli for experiments, I'm having a strange problem.
The desired outcome this time is to "shuffle" an image by dividing an image into segments of equal size and then swapping these randomly. This worked fine in initial tests and I swiftly forgot about the program. When my colleague tried it with her images though, the segments suddenly became smaller than they should be.
In order to illustrate the problem, I've filled each segment rectangle with a hatched brush:
Image pair A shows my initial results from a test image (downloaded from facebook). Image pair B shows the same operation applied to my colleagues test image; note that the hatched areas have gaps between them. The third image pair show the same effect after I modified the original image in GIMP and re-saved it. (I originally did this to see if the orientation had any effect - it didn't.)
It seems to me that 开发者_C百科the process of exporting the image from GIMP affected some property of the image such that the dimensions were interpreted incorrectly. Is there any way I can detect and correct this?
My code (edited for your sanity):
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;
}
--added as answer upon request of OP--
Just for the heck of it, I ported this to php and it works as you would expect (margins on the side, not margins around individual tiles. However, this brought me to the msdn page for drawimage(image,point), which seems to render the sepcified image based upon dpi of display device, rather than fixed pixel dimensions. Your crop function uses rect and specifies measurement which is per-pixel, but your re-draw routine uses a different method. Try using the drawimage method that you used in the crop function for the image reconstruction
There may be more to it, but I didn't notice a mechanism for dealing with the extra pixels in cases where the image size is not evenly divisible by the segment size. Is it possible your test case(s) were all a perfect fit?
assume a 100 x 100 image, 10 segments:
floor of 100/10 = 10; 10 x 10 = 100 pixels.
assume a 100 x 100 image, 13 segments:
floor of 100/13 = 7; 13 * 7 = 91 pixels.
精彩评论