简体   繁体   English

Photoshop像透明图像上的背景

[英]Photoshop like background on transparent image

I'm making a graphics editor for my class project and i want to make so that when, for example a user loads a picture in to the editor or or draw something in the PictureBox, all the alpha parts are shown the chessboard like background. 我正在为我的班级项目制作图形编辑器,并且希望这样做,例如,当用户将图片加载到编辑器中或在PictureBox中绘制某些内容时,所有的Alpha部分都像背景一样显示在棋盘上。

My idea is that when I create a PictureBox with transparent background set, I create another one behind it, set its BackColor to white and add grey images 50x50, alternately horizontally and vertically. 我的想法是,当我创建一个具有透明背景集的PictureBox时,我在其后面创建了另一个,将其BackColor设置为白色,并在水平和垂直方向交替添加50x50的灰度图像。 Is that a good approach to the problem? 这是解决问题的好方法吗? If, not do You have any suggestions? 如果没有,您有什么建议吗?

In Photoshop, for example, I create image 1600x1600. 例如,在Photoshop中,我创建图像1600x1600。 When I zoom to a certain level, it shrinks the boxes and adds more of them to fill the image. 当我缩放到某个级别时,它会缩小框并添加更多框以填充图像。 If You'we used Photoshop of similar program you know what I mean. 如果您使用过类似程序的Photoshop,您就会明白我的意思。 Now, how would I go about achieving the same effect? 现在,我将如何实现相同的效果?

Creating a Photoshop-like program is a fun project. 创建类似Photoshop的程序是一个有趣的项目。

There will be many challenges along your way and it is well worth thinking ahead a little.. 一路上会遇到许多挑战,因此值得一点思考。

Here is a short and incomplete list of things to keep in mind: 这里是要记住的简短且不完整的清单:

  • Draw- and paint actions 绘画动作
  • Undo, redo, edit 撤消,重做,编辑
  • Multiple layers 多层
  • Zooming and scrolling 缩放和滚动
  • Saving and printing 保存和打印

So getting a checkerboard background is only the start of a long journey.. 因此,获得棋盘格背景只是漫长旅程的开始。

Using a PictureBox as the base canvas is a very good choice, as its several layers will help. PictureBox用作基础画布是一个很好的选择,因为它的几层会有所帮助。 Here is a piece of code that will provide you with a flexible checkerboard background, that will keep its size even when you scale the real graphics: 这是一段代码,可为您提供灵活的棋盘背景,即使缩放实际图形时也能保持其大小:

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;
}

Load an Image for testing and this is what you'll get, left normal, right zoomed in: 加载一张图片进行测试,这就是您得到的结果(左正常,右放大):

在此处输入图片说明在此处输入图片说明

Yes, for saving this background should be removed; 是的,为保存此背景,应删除该背景; as you can see in the code, passing in a size = 0 will do that. 正如您在代码中看到的那样,传递size = 0可以做到这一点。

What next? 接下来是什么? Let me give you a few hints on how to approach the various tasks from above: 让我为您提供一些有关如何从上方执行各种任务的提示:

  • Scrolling: Picturebox can't scroll. 滚动: Picturebox无法滚动。 Instead place it in a Panel with AutoScroll = true and make it as large as needed. 而是将其放置在AutoScroll = truePanel ,并根据需要将其放大。

  • Zooming: Playing with its Size and the SizeMode will let you zoom in and out the Image without problems. 缩放:播放其SizeSizeMode可以让您放大和缩小Image而不会出现问题。 The BackgroundImage will stay unscaled, just as it does in Photoshop. 就像在Photoshop中一样, BackgroundImage将保持未缩放状态。 You will have to add some more code however to zoom in on the graphics you draw on top of the PB or on the layers. 但是,您将不得不添加更多代码,以放大在PB顶部或图层上绘制的图形。 The key here is scaling the Graphics object using a Graphics.MultiplyTransform(Matrix) . 此处的关键是使用Graphics.MultiplyTransform(Matrix)缩放Graphics对象。

  • Layers: Layers are imo the single most useful feature in PhotoShop (and other quality programs). 图层:图层是imo Photoshop(和其他高质量程序)中最有用的功能。 They can be achieved by nesting transparent drawing canvases. 它们可以通过嵌套透明的绘图画布来实现。 Panels can be used, I prefer Labels . 可以使用Panels ,我更喜欢使用Labels If each is sitting inside the one below it and the one at the bottom has the PB as its Parent , all their contents will be shown combined. 如果每个正坐在一个低于它和一个在底部里面有PB作为其Parent ,所有的内容将显示在组合。

    • Don't use the Label directly but create a subclass to hold additional data and know-how! 不要直接使用Label ,而是要创建一个subclass来保存其他数据和专有技术!
    • Changing their order is not very hard, just keep the nested structure in mind and intact! 更改顺序不是很困难,只需牢记嵌套结构并保持完整!
    • Hiding a layer is done by setting a flag and checking that flag in the painting actions 通过设置标志并在绘画操作中检查该标志来完成隐藏层的操作
    • Other data can include a Name, Opacity, maybe an overlay color.. 其他数据可以包括名称,不透明度,也可以是覆盖色。
    • The layers should also be shown in a Layers Palette, best by creating a thumbnail and inserting a layer userobject in a FlowLayoutPanel 图层也应该显示在“图层面板”中,最好通过创建缩略图并将图层userobject插入FlowLayoutPanel
  • Draw Actions: These are always the key to any drawing in WinForms . 绘图操作:这些始终是WinForms任何绘图的关键。 When using the mouse to draw, each such activity creates an object of a DrawAction class you need to design, which holds all info needed to do the actual drawing, like: 使用鼠标绘制时,每个这样的活动都会创建您需要设计的DrawAction类的对象,该对象包含进行实际绘制所需的所有信息,例如:

    • Type (Rectangle, filledRectangle, Line, FreeHandLine (a series of Points), Text, etc.etc..) 类型(矩形,实心矩形,直线,FreeHandLine(一系列点),文本等)。
    • Colors 色彩
    • Points 点数
    • Widths 宽度
    • Text 文本
    • The layer to draw on 要绘制的图层
    • maybe even a rotation 甚至旋转

    Along with the LayerCanvas class the DrawAction class will be the most important class in the project, so getting its design right is worth some work! 与LayerCanvas类一起,DrawAction类将是项目中最重要的类,因此正确进行设计值得一些工作!

    Only the topmost layer will receive the mouse events. 仅最顶层将接收鼠标事件。 So you need to keep track which layer is the active one and add the action to its actions list. 因此,您需要跟踪哪一层是活动层并将该动作添加到其动作列表中。 Of course the active layer must also be indicated in the Layers Palette. 当然,活动层也必须在“层调板”中指出。

  • Since all drawing is stored in List(s), implementing a unlimited undo and redo is simple. 由于所有图形都存储在列表中,因此实现无限的撤消和重做非常简单。 To allow for effective drawing and undo, maybe a common action list and an individual list for each layer is the best design.. 为了进行有效的绘制撤消操作,最好的方法是为每个图层设置一个共同的动作列表和一个单独的列表。

    • Undo and Redo are just matter of removing the last list element and pushing it onto a redo-stack. 撤消和重做只是删除最后一个列表元素并将其推入重做堆栈的问题。
    • Editing actions is also possible, including changing the parameters, moving them up or down the actions list or removing one from the middle of the list. 还可以编辑动作,包括更改参数,在动作列表中上移或下移参数或从列表中间删除一个。 It help to show an Actions Palette, like F9 in PhotoShop. 它有助于显示Actions Palette,例如PhotoShop中的F9。
    • To flatten two or more layers together all you need is to combine their action lists. 要将两个或多个层放在一起,您只需要将它们的动作列表合并即可。
    • To flatten all layers into the Image you only need to draw them not onto their canvas but into the Image. 要拼合所有图层到Image ,你只需要吸引他们没有他们的画布,但图像。 For the difference of drawing onto a control or into a Bitmap see here ! 绘制控制或位图的区别看这里 Here we have the PictureBox.Image as the second level of a PB's structure above the Background.Image . 在这里,我们将PictureBox.Image作为Background.Image上方PB结构的第二层。 (The 3rd is the Control surface, but with the multiple layers on top we don't really need it..) (第三个是“ Control表面,但是我们实际上不需要多层)。
  • Saving can be done by either by Image.Save() after flattening all Layers or after you have switched off the BackgroundImage by telling the PB to draw itself into a Bitmap ( control.DrawToBitmap() ) which you can then save. 平整所有图层后,可以通过Image.Save()进行保存,也可以通过告诉PB将其自身绘制到一个Bitmapcontrol.DrawToBitmap() )中来关闭BackgroundImage,然后进行保存。

Have fun! 玩得开心!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM