banner



How To Draw A Speech Bubble

  • Download demo - 20.69 KB
  • Download source - 26.83 KB

Screenshot 1

Screenshot 2

Screenshot 3

Screenshot 3

Introduction

I was working on a Windows Forms project that required the user to be able to add together speech balloons (also known as speech bubbles) on top of photographs or drawings. As I'm somewhat adept with GDI+, I figured it wouldn't be also complicated; I'd either use a GraphicsPath or a Region. Ultimately, I wanted to draw the balloon, marriage information technology with a tail, fill the resulting shape, and depict its outline. I knew Region had a Union method, so I tried that ane first. The spousal relationship worked just fine, only while I was able to fill the combined shapes area with the background color, in that location is no Draw method for regions in GDI+, thus I was unable to draw the outline of the speech balloon. If I tried to describe the outlines of the individual shapes using the two GraphicsPath objects, the outlines would intersect with each other and not work at all.

I so tried GraphicsPath, and while GDI+ has both Fill and Describe methods for it, there's no way to spousal relationship 2 GraphicsPath objects into ane shape, and I was left with the same trouble for drawing the edge equally I was with Region.

I as well looked into whether there'southward a way to convert from a Region to a GraphicsPath (in order to get a GraphicsPath object from a unioned Region), just there wasn't. At that point, I stopped trying to figure it out by myself, and vicious back on the programmer'south best friend, the Internet. Searching for solutions online (where I actually constitute a few people asking how to make voice communication balloons), the resounding respond was that you cannot exercise this due to the limitations of GDI+ and the Region and GraphicsPath classes (which I mentioned above). This article describes how I worked around the problem, and provides a sample awarding that you can employ to generate your own voice communication balloon images or generate the code required to replicate the airship you design.

Background

Anatomy of a Speech Balloon

To help make my code and the sample program a little easier to follow, I'one thousand going to provide some basic terminology. I've fabricated most of this stuff upwards in a way that makes sense to me, so to actual comic artists out there who know all the technical terms for these $.25 and pieces, I apologize if I'm not using the right names.

Anatomy

Regardless of what blazon of balloon (oral communication, thought, starburst) we're talking virtually, the central expanse is called the balloon. The protrusions around the perimeter of the balloon (bubbles for thought balloons, spikes or rays for the starbursts) I simply call bubbling. What's the difference between thought balloon bubbles and starburst bubbles, you might ask? The difference is that starburst bubbles are sharper than thought balloon bubbles. The single protrusion that points to the speaker (or thinker) of the airship, I call the tail.

Requirements

Drawing a speech balloon involves two parts: drawing the actual balloon itself (with its bubbles), and drawing the tail. Because I like to make things every bit generic and reusable equally possible, my spoken language balloon drawing system had to back up the following requirements:

  • The ability to have any text in the balloon
  • The power to specify the colors of the text, the balloon fill color, and the border color
  • The ability to set the font used to draw the text
  • The power to show or hibernate the border
  • The ability to show or hide the tail
  • The ability to change the size and orientation of the tail around the balloon
  • The power to alter the shape of the balloon to simulate oral communication (ellipse), thought (bubbly ellipse), and actions (starburst)

The SpeechBalloon Grade

In my solution, I created a new form chosen SpeechBalloon which holds all the backdrop of the speech airship nosotros can set, as well as the method for actually rendering the airship into a Graphics object. I'yard not going to bother going into the details of pedestrian properties like Font, Bounds, BorderWidth, etc., as they should be pretty self-explanatory and the code is well-commented.

The GraphicsPath object that holds the shape of the balloon is stored in a read-simply property named Path. I buffer the GraphicsPath instead of re-creating it on each phone call to Depict every bit information technology can exist a circuitous process (every bit we'll meet below). Each of the other properties, when changed, will crusade the path to be recreated (if the said property affects the airship's shape), and volition raise an event, RedrawRequired, on the SpeechBalloon instance to inform the parent programme that the oral communication balloon needs to exist redrawn on its drawing surface. Here are some examples:

This belongings changes the shape of the balloon and causes our lawmaking to regenerate its GraphicsPath (via the RecreatePath method):

          Public          Property          Width()          As          Integer          Become          Return          MyBounds.Width          Terminate          Get          Set(ByVal          value          As          Integer)          Dim          inverse          As          Boolean          = value <> MyBounds.Width          MyBounds.Width = value          If          changed          Then          RecreatePath()          RaiseEvent          RedrawRequired(Me, EventArgs.Empty)          End          If          End          Set          End          Property        

This property does non alter the shape of the balloon (and thus only raises the RedrawRequired event):

          Private          MyFillColor          As          Color = Color.White          Public          Holding          FillColor()          Equally          Color          Become          Return          MyFillColor          End          Go          Gear up(ByVal          value          Equally          Color)          Dim          changed          Equally          Boolean          = value <> MyFillColor          MyFillColor = value          If          inverse          Then          RaiseEvent          RedrawRequired(Me, EventArgs.Empty)          Stop          Set up          End          Belongings        

Creating the Balloon

The individual RecreatePath method in the SpeechBalloon class creates our balloon's GraphicsPath buffer. To create the bubbling around the airship, we're going to look at three properties of the SpeechBalloon course: BubbleWidth, which specifies how many degrees broad a single chimera is on the perimeter of the airship; BubbleSize, which determines how far from the balloon the bubbles protrude; and BubbleSmoothness, which determines whether our bubbles will exist soft and curvy (as in idea balloons) or hard and sharp (equally in starbursts).

The first thing RecreatePath does is clear the buffer:

          Private          Sub          RecreatePath()        Path.Reset()

If our BubbleSize property is set to 0, we have a elementary speech airship, and GraphicPath'due south AddEllipse method is all nosotros demand:

            If          BubbleSize =          0          Then          Path.AddEllipse(0,          0, Width, Height)

Otherwise, we're going to have to exercise some work to make these bubbles. For each bubble, we need iii points: the starting point of the bubble forth the airship's ellipse, the ending point of the bubble along the balloon's ellipse, and a point between the two that is positioned abroad from the perimeter of the balloon (as determined by BubbleSize).

I won't bore you with the loop details and trig required to summate those three points, but y'all can await at the code (which I've tried to annotate as best as I can) for more details. Suffice it to say that I was never that proficient at trigonometry, merely I learned enough to know how to find the formulae I needed online:

          Else          Dim          theta          Equally          Integer          =          0                             For          theta =          0          To          (360          - BubbleWidth)          Step          +BubbleWidth          Dim          points(2)          As          Point                                                                                                                        points(0) =          New          Point(ten, y)             points(1) =          New          Point(x2, y2)             points(2) =          New          Signal(x3, y3)                                        Path.AddCurve(points, BubbleSmoothness)          Side by side                   Path.CloseAllFigures()          End          If          Finish          Sub        

As you tin can see, the GraphicsPath.AddCurve method takes a parameter that determines how curve-similar the resulting bend is. A value of 0.0 creates a triangular shape. A value of 1.0 creates a perfect curve. Annihilation greater than 1.0 does strange things (experience complimentary to experiment with my sample app).

Creating the Tail

To keep things simple, the only tail I support is a triangular one, and its drawing origin is located at the eye of the airship. There are three properties on the SpeechBalloon class associated with the tail: TailLength, which is the altitude from a perfectly vertical tail from the top of the airship; TailBaseWidth (referred to every bit Tail Width in the sample app), which is the width of the base of the triangle; and TailRotation, which determines at what angle around the speech balloon the tail is going to signal towards. I always draw an upward tail and use TailRotation with Graphics.RotateTransform to spin it into position.

Since tail creation is very elementary, I recreate the tail equally part of each call to the Draw method on SpeechBalloon:

                   tail.AddLine(-TailBaseWidth,          0, TailBaseWidth,          0) tail.AddLine(TailBaseWidth,          0,          0, -(TailLength + (Meridian \          2)))  tail.CloseFigure()

Putting information technology All Together

Now that I accept my balloon path and my tail path, I had to overcome the challenge of how I was going to fill and outline them both equally if they were i shape. After some trial and error, I discovered a relatively simple fashion to it:

  1. Draw the tail'south border, twice as thick as the airship's edge. When the airship is filled, it volition cover upwardly the part of the tail edge that is drawn under the airship itself.
  2. Make full the balloon'south path using the background colour.
  3. Draw the balloon'southward border.
  4. Make full the tail's path using the background colour. This ensures that the outer border of the balloon where it meets the tail is colored over with the background colour, giving the illusion that the tail and the balloon are all one big happy object, plus it covers up half of the tail's border (which we drew double-sized) to make it look as wide as the residue of the balloon'southward edge.

In lawmaking, that translates to the following:

            If          TailVisible          AndAlso          BorderVisible          Then                         Dim          thickPen          Every bit          New          Pen(BorderColor, BorderWidth *          2.0)           gstate = yard.Save()           g.TranslateTransform(Left() + (Width /          2), Top + (Height /          2))           g.RotateTransform(TailRotation)           g.DrawPath(thickPen, tail)           g.Restore(gstate)          End          If           gstate = 1000.Save()   grand.TranslateTransform(Left, Top)   g.FillPath(fillBrush, Path)             If          BorderVisible          Then          g.DrawPath(borderPen, Path)          Finish          If           g.Restore(gstate)            If          TailVisible          Then               gstate = g.Save()           g.TranslateTransform(Left() + (Width /          2), Summit + (Tiptop /          two))           chiliad.RotateTransform(TailRotation)                               grand.FillPath(fillBrush, tail)           1000.Restore(gstate)          End          If        

Once that'due south all washed, at that place's only one matter left to do; draw the text:

            sf.LineAlignment = StringAlignment.Middle sf.Alignment = StringAlignment.Heart   g.DrawString(Text, Font, textBrush, Premises, sf)

Using the Code

The sample application I've provided makes using the lawmaking very easy equally it volition generate the VB.NET code needed to reproduce the speech balloon you visually design with information technology.

To rapidly apply the code in your project, follow these steps:

  1. Copy SpeechBalloon.vb from the sample application into your awarding.
  2. Run the sample application.
  3. Fiddle with the settings until you have the balloon that y'all want.
  4. Under the "File" bill of fare, select "Generate Code...". The VB.NET code required to reproduce that balloon volition be displayed below it.
  5. Copy the generated code from the sample awarding and paste it into your application.
  6. At some betoken in your awarding, call the Draw method on the instance of the speech balloon, passing information technology the appropriate Graphics object.

Super Happy Bonus

I've built the demo application so that information technology tin as well export the speech balloon you lot pattern to a Portable Network Graphics (PNG) file. Savour!

I made an attempt to comment the demo application code (all in Form1.vb in the sample code), so if you're interested to see how I wrote the demo app, feel free to await through it.

Possible Enhancements

While I think my fiddling speech balloon generator is bang-up, it does have its shortcomings. Here are a listing of possible features that I think would be neat enhancements:

  • The generator could utilize a double-buffer to reduce the flickering when redrawing the balloon. I didn't want to complicate the sample lawmaking with that.
  • Support for rich text in the airship.
  • Support for rectangular balloons (commonly used in comics to show electronic or not-human communication). - See History Beneath
  • Ability to have fancy tails (curved, lightning-bolt shaped, little puffs of clouds for idea balloons, etc.).
  • Ability to have random-sized bubbling to give a less uniform appearance for starbursts and idea balloons.
  • Ability to have the balloon describe its own semi-transparent (i.e., alpha-blended) driblet shadow.
  • Ability to accept several balloons continued by small bridging lines (used in comics to separate pieces of a conversation in i panel).

History

  • 2010/01/09 - Initial version
  • 2010/11/xiv - Added support for rectangular (and round-rectangular) balloons, with adjustable corner radius

Source: https://www.codeproject.com/Articles/51377/Creating-a-Speech-Balloon-Speech-Bubble-in-GDI

Posted by: kendallmouldither1967.blogspot.com

0 Response to "How To Draw A Speech Bubble"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel