Jump to content
How to Install Plugins ×
Paint.NET 5.1 is now available! ×

Recommended Posts

Posted

As requested here: https://forums.getpaint.net/topic/112938--/

 

Dimensions

Effects > Render > Dimensions

 

Description

Render dimension arrows on your canvas.  This will NOT measure anything and will NOT convert pixel length to another unit of length.

 

DimensionsUI.png

 

Until I add this to my plugin pack, download here:

Download

 

Save to your desktop, unzip files to your desktop and run the installer batch file.

 

 

Source Code: (This was a quick hack, mostly cobbled together from other plugins, and the code is ugly. You have been warned.)

Spoiler

// Name: Dimensions
// Submenu: Render
// Author: BoltBait
// Title: BoltBait's Dimensions v1.2
// Version: 1.2
// Desc: Render |<---5"--->|
// Keywords: arrow, arrows, dimension, dimensions
// URL: http://BoltBait.com/pdn
#region UICode
PanSliderControl Amount1 = Pair.Create(-0.900,0.000); // Start Position
PanSliderControl Amount2 = Pair.Create(0.900,0.000); // End Position
IntSliderControl Amount3 = 3; // [1,100] Line Width
ColorWheelControl Amount4 = ColorBgra.FromBgr(0,0,255); // [PrimaryColor] Line Color
TextboxControl Amount5 = "TEST"; // [0,255] Label
CheckboxControl Amount6 = true; // [0,1] Rotate Label
CheckboxControl Amount7 = true; // [0,1] Ticks
#endregion

float ArrowHeadFactor = 3.0f;
private UserBlendOp normalOp = new UserBlendOps.NormalBlendOp(); // Normal

void Render(Surface dst, Surface src, Rectangle rect)
{
    dst.Clear(rect,Color.Transparent);
    Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
    ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
    int width = selection.Right - selection.Left;
    int height = selection.Bottom - selection.Top;

    double StartX = (Amount1.First + 1) / 2;
    double StartY = (Amount1.Second + 1) / 2;
    double EndX = (Amount2.First + 1) / 2;
    double EndY = (Amount2.Second + 1) / 2;

    // Calculate rotation angle
    float X1 = (float)((Amount1.First + 1) / 2 * (selection.Right - selection.Left) + selection.Left);
    float Y1 = (float)((Amount1.Second + 1) / 2 * (selection.Bottom - selection.Top) + selection.Top);
    float X2 = (float)((Amount2.First + 1) / 2 * (selection.Right - selection.Left) + selection.Left);
    float Y2 = (float)((Amount2.Second + 1) / 2 * (selection.Bottom - selection.Top) + selection.Top);

    float deltaX = X2 - X1;
    float deltaY = Y2 - Y1;
    float angle;
    if (deltaX == 0 && deltaY == 0)
    {
        // special case: when both +'s are on the same spot, don't rotate
        angle = 0;
    }
    else
    {
        angle = ((float)Math.Atan2(deltaX, deltaY) * 180 / (float)Math.PI) - 90;
    }

    // we can now convert these to actual pixel co-ordinates.
    int StartColumn = (int)Math.Round(StartX * width) + selection.Left;
    int StartRow = (int)Math.Round(StartY * height) + selection.Top;
    int EndColumn = (int)Math.Round(EndX * width) + selection.Left;
    int EndRow = (int)Math.Round(EndY * height) + selection.Top;
    int CenterColumn = (StartColumn + EndColumn) / 2;
    int CenterRow = (StartRow + EndRow) / 2;

    Graphics g = new RenderArgs(dst).Graphics;
    g.Clip = new Region(rect);
    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
    Pen myPen = new Pen(Amount4);
    myPen.Width = Amount3;
    SolidBrush Brush2 = new SolidBrush(Amount4.ToColor());

    GraphicsPath p = new GraphicsPath();
    Brush b = new SolidBrush(Amount4);

    // Draw Starting line end
    PointF p1 = new PointF(StartColumn + (Amount3 * ArrowHeadFactor), StartRow - (Amount3 * ArrowHeadFactor));
    PointF p2 = new PointF(StartColumn,StartRow);
    PointF p3 = new PointF(StartColumn + (Amount3 * ArrowHeadFactor), StartRow + (Amount3 * ArrowHeadFactor));
    p.AddPolygon(new PointF[] { p2, p3, p1});
    if (Amount7)
    {
        p.AddRectangle(new RectangleF(p2.X-Amount3,p1.Y, Amount3,Math.Abs(p3.Y-p1.Y) * 1.5f));
    }
    Matrix translateMatrix = new Matrix();
    translateMatrix.RotateAt(-angle, p2);
    p.Transform(translateMatrix);
    translateMatrix.Dispose();
    g.FillPath(Brush2, p);
    p.Reset();

    // Draw Ending line end
    p1 = new PointF(EndColumn - (Amount3 * ArrowHeadFactor), EndRow + (Amount3 * ArrowHeadFactor));
    p2 = new PointF(EndColumn,EndRow);
    p3 = new PointF(EndColumn - (Amount3 * ArrowHeadFactor), EndRow - (Amount3 * ArrowHeadFactor));
    p.AddPolygon(new PointF[] { p2, p3, p1});
    if (Amount7)
    {
        p.AddRectangle(new RectangleF(p2.X,p3.Y, Amount3,Math.Abs(p3.Y-p1.Y) * 1.5f));
    }
    translateMatrix = new Matrix();
    translateMatrix.RotateAt(-angle, p2);
    p.Transform(translateMatrix);
    translateMatrix.Dispose();
    g.FillPath(Brush2, p);
    p.Reset();

    // Draw main line
    myPen.EndCap = LineCap.ArrowAnchor;
    myPen.StartCap = LineCap.ArrowAnchor;
    g.DrawLine(myPen,(int)StartColumn,(int)StartRow,(int)EndColumn,(int)EndRow);

    // Draw Text (This is not the easiest way to draw text, so don't copy this.)
    StringFormat sf = new StringFormat();
    sf.Alignment = StringAlignment.Center;
    sf.LineAlignment = StringAlignment.Center;
    SolidBrush Brush1 = new SolidBrush(ColorBgra.Transparent);
    Pen tpn = new Pen(Brush1, Amount3 * 3);
    tpn.LineJoin = LineJoin.Round;
    g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
    p.AddString(Amount5, new FontFamily("Arial"), (int)FontStyle.Regular, g.DpiY * (Amount3 * 3) / 72, new Point(CenterColumn, CenterRow), sf);
    if (Amount6)
    {
        translateMatrix = new Matrix();
        translateMatrix.RotateAt(-angle,new Point(CenterColumn, CenterRow));
        p.Transform(translateMatrix);
        translateMatrix.Dispose();
    }
    g.CompositingMode = CompositingMode.SourceCopy;
    g.DrawPath(tpn, p);
    g.CompositingMode = CompositingMode.SourceOver;
    g.FillPath(Brush2, p);

    // Now combine what we've drawn with the source canvas
    for (int y = rect.Top; y < rect.Bottom; y++)
    {
        for (int x = rect.Left; x < rect.Right; x++)
        {
            dst[x,y] = normalOp.Apply(src[x,y],dst[x,y]);
        }
    }
    
    // clean up
    myPen.Dispose();
    g.Dispose();
    tpn.Dispose();
    p.Dispose();
    b.Dispose();
    Brush1.Dispose();
    Brush2.Dispose();
}

As I said, this should be cleaned up because the section on calculating the starting and ending coordinates contains a bunch of duplication because I simply copies large blocks of code from other plugins.

 

Versions:

1.2 7/1/2018 Fixed a bug where it would clear the canvas when OK was clicked.

1.1 7/1/2018 Text surrounded by transparency instead of white.

1.0 6/30/2018 Initial Release.

  • Like 1
  • Upvote 6
Posted (edited)

After OK the dimension disappears from the canvas and the background color is deleted.

Edited by xod
Posted

It only takes seconds to use line/curve, customise the ends, add the measurement (in the font of choice) and rotate/place where required.

 

Yes, the measurement isn't mid-line, but that only takes a few seconds more.

 

And it works.

TV Avatar 500 x 150 DALEK 2  .png

Posted
3 hours ago, xod said:

After OK the dimension disappears from the canvas and the background color is deleted.

 

You're right.  Something has gone wrong with my latest build. ?

 

EDIT:  This has been fixed now.  For the dozen people who downloaded v1.1, download v1.2 and everything will be fine.  Sorry about that!

 

2 hours ago, GillFelis said:

It only takes seconds to use line/curve, customise the ends, add the measurement (in the font of choice) and rotate/place where required.

 

Yes, the measurement isn't mid-line, but that only takes a few seconds more.

 

And it works.

 

If you don't find it handy, don't download it. Not every plugin is for everyone.  In this case, someone requested the plugin. So, I'm sure at least 1 person will find it handy.

  • Like 1
  • Upvote 1
Posted (edited)

Thanks for your effort, for the plugin, and also for the code.
For me it is very useful. beer-2-smiley-emoticon.png beer-2-smiley-emoticon.png beer-2-smiley-emoticon.png

Edited by xod
  • 1 year later...
Posted

Please make it more of a painting type tool: use it like the line tool and then a menu pops up for text label, fiddling with 4 sliders for many parts is annoying.

Posted

Plugins do not have the same abilities as Tools. What you're asking for is beyond the present plugin model without a HUGE amount of work (i.e. making a custom interface like Liquify)

  • Like 1
  • Upvote 1

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...