Photoshop喜欢透明图像上的背景
我正在为我的课程项目制作一个图形编辑器,我想这样做,例如当用户将图片加载到编辑器中或者在PictureBox中绘制某些东西时,所有的alpha部分都显示为棋盘状的背景。
我的想法是,当我创建一个具有透明背景设置的PictureBox时,我在它后面创建另一个,将BackColor设置为白色并在水平和垂直方向上交替添加灰色图像50×50。 这是解决问题的好方法吗? 如果,不是吗?你有什么建议吗?
例如,在Photoshop中,我创建图像1600×1600。 当我缩放到某个级别时,它缩小了框并添加了更多的框来填充图像。 如果你使用类似程序的Photoshop你知道我的意思。 现在,我将如何实现同样的效果?
创建类似Photoshop的程序是一个有趣的项目。
沿途会有很多挑战,值得提前考虑一下……
以下是一个简短而不完整的事项清单:
- 绘画和绘画动作
- 撤消,重做,编辑
- 多层
- 缩放和滚动
- 保存和打印
所以获得棋盘背景只是漫长旅程的开始..
使用PictureBox
作为基础canvas是一个非常好的选择,因为它的几个层将有所帮助。 下面是一段代码,它将为您提供灵活的棋盘背景,即使在缩放真实图形时也会保持其大小:
void setBackGround(PictureBox pb, int size, Color col) { if (size == 0 && pb.BackgroundImage != null) { pb.BackgroundImage.Dispose(); pb.BackgroundImage = null; return; } Bitmap bmp = new Bitmap(size * 2, size * 2); using (SolidBrush brush = new SolidBrush(col)) using (Graphics G = Graphics.FromImage(bmp) ) { G.FillRectangle(brush, 0,0,size, size); G.FillRectangle(brush, size,size, size, size); } pb.BackgroundImage = bmp; pb.BackgroundImageLayout = ImageLayout.Tile; }
加载图像进行测试,这是你将得到的,左边正常,右边放大:
是的,为了保存这个背景应该被删除; 正如你在代码中看到的那样,传入一个size = 0就可以了。
接下来是什么? 让我给你一些关于如何处理上述各种任务的提示:
-
滚动:
Picturebox
无法滚动。 而是将其放在具有AutoScroll = true
的Panel
,并根据需要将其设置为大。 -
缩放:使用其
Size
和SizeMode
可以放大和缩小Image
而不会出现问题。BackgroundImage
将保持不缩放,就像在Photoshop中一样。 您将不得不添加更多代码,以放大在PB顶部或图层上绘制的图形。 这里的关键是使用Graphics.MultiplyTransform(Matrix)
缩放Graphics
对象。 -
图层:图层是PhotoShop(和其他质量程序)中最有用的function。 它们可以通过嵌套透明绘图canvas来实现。 可以使用
Panels
,我更喜欢Labels
。 如果每个人都坐在它下面的那个中,而底部的那个人将PB作为其Parent
,那么他们的所有内容将被合并显示。- 不要直接使用
Label
,而是创建一个subclass
来保存其他数据和专有技术! - 改变他们的顺序并不是很难,只需记住嵌套结构并保持完整!
- 隐藏图层是通过设置标志并在绘画操作中检查该标志来完成的
- 其他数据可能包括名称,不透明度,可能是叠加颜色..
- 图层也应该显示在图层调色板中,最好通过创建缩略图并在
FlowLayoutPanel
插入图层userobject
- 不要直接使用
-
绘制操作:这些始终是
WinForms
任何绘图的关键。 使用鼠标绘制时,每个此类活动都会创建一个您需要设计的DrawAction
类的对象,该对象包含进行实际绘制所需的所有信息,如:- Type(Rectangle,filledRectangle,Line,FreeHandLine(一系列点),Text等等。)
- 颜色
- 点
- 宽度
- 文本
- 要绘制的图层
- 也许甚至是轮换
与LayerCanvas类一起,DrawAction类将是项目中最重要的类,因此正确设计它是值得的一些工作!
只有最顶层才会收到鼠标事件。 因此,您需要跟踪哪个层是活动层,并将操作添加到其操作列表中。 当然,活动层也必须在图层调色板中指示。
-
由于所有绘图都存储在List(s)中,因此实现无限制的撤消和重做很简单。 为了实现有效的绘制和撤消,每个图层的常用操作列表和单个列表可能是最佳设计。
- 撤消和重做只是删除最后一个列表元素并将其推送到重做堆栈的问题。
- 编辑操作也是可能的,包括更改参数,在动作列表中向上或向下移动参数或从列表中间删除参数。 它有助于显示一个动作调色板,如PhotoShop中的F9。
- 要将两个或多个图层拼合在一起,您只需要合并其动作列表即可。
- 要将所有图层展平为
Image
您只需要将它们绘制到canvas上,而不是绘制到图像中。 有关绘制到控件或位图的区别, 请参阅此处 ! 这里我们将PictureBox.Image
作为Background.Image
上方PB结构的第二层。 (第3个是Control
界面,但顶部有多个层,我们真的不需要它……)
-
可以通过
Image.Save()
在展平所有图层之后或通过告诉PB将自身绘制到可以保存的Bitmap
(control.DrawToBitmap()
)来关闭BackgroundImage来完成保存。
玩得开心!