如何根据 column/row 输入和边距变量将最大图像放置在空白位图中并保持图像的纵横比
How to place maximum images in a blank Bitmap based on column/row input & margin variables and preserving aspect ratio of images
这可能是一个棘手的问题。
我开门见山。
首先我制作一个空白位图图像:
Bitmap MasterImage = new Bitmap(PageSize.Width, PageSize.Height, PixelFormat.Format32bppArgb);
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(MasterImage);
之后:
我得到了一个参数,表示我想根据列和行在空白位图(页面)中放置多少图像:
int numOfColumns=2; //(could be any value)
int numOfRows=4;
所以我们应该得到这样的东西:
如果我在顶部图像和左侧图像上有一些边距,我也会得到一个参数:
int PagetopMargin=0; //(could be any value)
int PageLeftMargin=0;
我有一个名为:imagesPath
的变量,它是 List<String>
的类型,它包含图像的完整路径。
现在我循环浏览图像:
while (imagesPath.Count > 0)
{
Image image = Image.FromFile(imagesPath[0]);
//Logic comes here.
//after finishing processing and drawing images in Bitmap i remove image from list
imagesPath.RemoveAt(0);
}
我想要实现的是如何根据 column/row 和边距变量在该位图页面中放置最大图像并保持图像的纵横比。 (因此图像不会失真)。如果留下一些图像,没关系,我将继续下一个空白位图来放置它们。只需要将位图空白图像填充到完整即可。
这是一个函数,可以将一个矩形放入另一个矩形中,居中或不居中(对齐 top-left):
Rectangle FitToBox(Rectangle scr, Rectangle dest, bool centered)
{
var ratioX = (double)dest.Width / scr.Width;
var ratioY = (double)dest.Height / scr.Height;
var ratio = Math.Min(ratioX, ratioY);
var newWidth = (int)(scr.Width * ratio);
var newHeight = (int)(scr.Height * ratio);
if (!centered)
return new Rectangle(0, 0, newWidth, newHeight);
else
return new Rectangle((dest.Width - newWidth) / 2,
(dest.Height - newHeight) / 2, newWidth, newHeight);
}
其基本数学形式为 this post。
这是一个测试台,使用不同的随机值居中和不居中:
Random rnd = new Random();
int cols = rnd.Next(3) + 2;
int rows = rnd.Next(4) + 3;
int w = pan_dest.Width / cols;
int h = pan_dest.Height / rows;
using (Graphics G = pan_dest.CreateGraphics())
{
G.Clear(Color.White);
for (int c = 0; c < cols; c++)
for (int r = 0; r < rows; r++)
{
Rectangle rDest = new Rectangle(c * w, r * h, w, h);
Rectangle rSrc = new Rectangle(0, 0, rnd.Next(200) + 10, rnd.Next(200) + 10);
Rectangle rResult = FitToBox(rSrc, rDest, checkBox1.Checked);
Rectangle rDestPlaced = new Rectangle(c * w + (int)rResult.X,
r * h + rResult.Y, rResult.Width, rResult.Height);
using (Pen pen2 = new Pen(Color.SlateGray, 4f))
G.DrawRectangle(pen2, Rectangle.Round(rDest));
G.DrawRectangle(Pens.Red, rDestPlaced);
G.FillEllipse(Brushes.LightPink, rDestPlaced);
}
}
然后您将像这样绘制图像:
G.DrawImage(someImageimg, rDestPlaced, rSrc, GraphicsUnit.Pixel);
这会最大化图像 大小 ,而不是您在评论中指定的页面上可以容纳的图像 数量 。对于后者,您应该查看 2-dimensional packing..
之类的内容
这可能是一个棘手的问题。
我开门见山。 首先我制作一个空白位图图像:
Bitmap MasterImage = new Bitmap(PageSize.Width, PageSize.Height, PixelFormat.Format32bppArgb);
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(MasterImage);
之后: 我得到了一个参数,表示我想根据列和行在空白位图(页面)中放置多少图像:
int numOfColumns=2; //(could be any value)
int numOfRows=4;
所以我们应该得到这样的东西:
如果我在顶部图像和左侧图像上有一些边距,我也会得到一个参数:
int PagetopMargin=0; //(could be any value)
int PageLeftMargin=0;
我有一个名为:imagesPath
的变量,它是 List<String>
的类型,它包含图像的完整路径。
现在我循环浏览图像:
while (imagesPath.Count > 0)
{
Image image = Image.FromFile(imagesPath[0]);
//Logic comes here.
//after finishing processing and drawing images in Bitmap i remove image from list
imagesPath.RemoveAt(0);
}
我想要实现的是如何根据 column/row 和边距变量在该位图页面中放置最大图像并保持图像的纵横比。 (因此图像不会失真)。如果留下一些图像,没关系,我将继续下一个空白位图来放置它们。只需要将位图空白图像填充到完整即可。
这是一个函数,可以将一个矩形放入另一个矩形中,居中或不居中(对齐 top-left):
Rectangle FitToBox(Rectangle scr, Rectangle dest, bool centered)
{
var ratioX = (double)dest.Width / scr.Width;
var ratioY = (double)dest.Height / scr.Height;
var ratio = Math.Min(ratioX, ratioY);
var newWidth = (int)(scr.Width * ratio);
var newHeight = (int)(scr.Height * ratio);
if (!centered)
return new Rectangle(0, 0, newWidth, newHeight);
else
return new Rectangle((dest.Width - newWidth) / 2,
(dest.Height - newHeight) / 2, newWidth, newHeight);
}
其基本数学形式为 this post。
这是一个测试台,使用不同的随机值居中和不居中:
Random rnd = new Random();
int cols = rnd.Next(3) + 2;
int rows = rnd.Next(4) + 3;
int w = pan_dest.Width / cols;
int h = pan_dest.Height / rows;
using (Graphics G = pan_dest.CreateGraphics())
{
G.Clear(Color.White);
for (int c = 0; c < cols; c++)
for (int r = 0; r < rows; r++)
{
Rectangle rDest = new Rectangle(c * w, r * h, w, h);
Rectangle rSrc = new Rectangle(0, 0, rnd.Next(200) + 10, rnd.Next(200) + 10);
Rectangle rResult = FitToBox(rSrc, rDest, checkBox1.Checked);
Rectangle rDestPlaced = new Rectangle(c * w + (int)rResult.X,
r * h + rResult.Y, rResult.Width, rResult.Height);
using (Pen pen2 = new Pen(Color.SlateGray, 4f))
G.DrawRectangle(pen2, Rectangle.Round(rDest));
G.DrawRectangle(Pens.Red, rDestPlaced);
G.FillEllipse(Brushes.LightPink, rDestPlaced);
}
}
然后您将像这样绘制图像:
G.DrawImage(someImageimg, rDestPlaced, rSrc, GraphicsUnit.Pixel);
这会最大化图像 大小 ,而不是您在评论中指定的页面上可以容纳的图像 数量 。对于后者,您应该查看 2-dimensional packing..
之类的内容