This project has moved. For the latest updates, please go here.

Beginners question

Apr 19, 2016 at 7:38 PM
Hi,

I am trying to create an image which I have written out in batch convert first.
convert 3508x2480empty.png  -fill none -stroke black -strokewidth 1 -draw "rectangle 10,10 310,110" -pointsize 34 -font Arial -fill black -strokewidth 1 -draw "text 100,40 'COMP1'" -pointsize 18 -draw "text 20,60 '34 vs 18 points'" 3508x2480rectangle1.png
convert 3508x2480rectangle1.png  -fill none -stroke black -strokewidth 1 -draw "rectangle 10,210 310,310" -pointsize 34 -font Arial -fill black -strokewidth 0 -draw "text 100,240 'COMP2'" -pointsize 22 -draw "text 20,260 '34 vs 22 points'" 3508x2480rectangle2.png
convert 3508x2480rectangle2.png -stroke black -draw "line   160,110 160,210" 3508x2480rectangle3.png
This create two boxes with a line between them. And now I want to do the same from C#. Since these are also multiple draws I try to follow this example: TEXT

But that gives me the error of not finding the type of DrawableBase. What I am doing wrong?
How should I implement these convert commands into c#? They all apply to the same image.
Coordinator
Apr 24, 2016 at 11:16 AM
Edited Apr 24, 2016 at 11:16 AM
The DrawableBase class has been deprecated. Below is a step by step translation of your command:
// You can also create an empty (I hope you mean transparent) image instead of
// reading 3508x2480empty.png 
using (MagickImage image = new MagickImage(MagickColors.Transparent, 3508, 2480))
{
  image.Draw(
    new DrawableFillColor(MagickColors.Transparent), // -fill none
    new DrawableStrokeColor(MagickColors.Black), // -stroke black
    new DrawableStrokeWidth(1), // -strokewidth 1
    new DrawableRectangle(10, 10, 310, 110), // -draw "rectangle 10,10 310,110"
    new DrawableFontPointSize(34), // -pointsize 34
    new DrawableFont("Arial"), // -font Arial
    new DrawableFillColor(MagickColors.Black), // -fill black
    // Don't need -strokewidth 1 because it already has this value
    new DrawableText(100, 40, "COMP1"), // -draw "text 100,40 'COMP1'"
    new DrawableFontPointSize(18), // -pointsize 18
    new DrawableText(20, 60, "34 vs 18 points"), // -draw "text 20,60 '34 vs 18 points'"

    // We can just continue drawing instead of writing to 3508x2480rectangle1.png
    new DrawableFillColor(MagickColors.Transparent), // -fill none
    // Skip: -fill none -stroke black -strokewidth 1
    new DrawableRectangle(10, 210, 310, 310), // -draw "rectangle 10,210 310,310"
    new DrawableFontPointSize(34), // -pointsize 34
    // Skip: -font Arial
    new DrawableFillColor(MagickColors.Black), // -fill black
    new DrawableStrokeWidth(0), // -strokewidth 0
    new DrawableText(100, 240, "COMP2"), // -draw "text 100,240 'COMP2'"
    new DrawableFontPointSize(22), // -pointsize 22
    new DrawableText(20, 260, "34 vs 22 points"), // -draw "text 20,60 '34 vs 22 points'"

    // Continue drawing instead of writing to 3508x2480rectangle2.png
    // Skip: -stroke black
    new DrawableLine(160, 110, 160, 210) // -draw "line   160,110 160,210"
  );

  image.Write(@"3508x2480rectangle3.png");
}
Apr 24, 2016 at 4:17 PM
Dirk,

Thanks very much! Very clearly explained.
Are all the "new Draw" actions immediately executed or only when the Write goes?

I don't like the syntax of this way of working.
I am not a very experienced C# programmer so the whole using thing is not my thing. My program is a command line generator and runs for about 19 pictures with schemas on them, I think the GC phase will never be reached anyway :-).
I am guessing I am not able to do another image.Draw outside the using {} scope?
In your other example all the commands are part of a List I guess. The way I do it now works as well for me.
I am just in the process of replacing all my batch convert commands into your class......

I am drawing many boxes on the canvas which sort of logically are created while traversing through an input xml document in a list. So with some struggling I am now able to do it like this.
And yes, empty is transparant :-).
MagickImage image = new MagickImage("3508x2480empty.png");
DrawableFont arial = new DrawableFont("Arial");
image.Settings.FontPointsize = 68;
DrawableText tekst = new DrawableText(200,200,"tesetsetest");
tekst.Value = clusterclean;
tekst.X = titlecenter;
tekst.Y = 200;
image.Draw(tekst);
... logic ....
DrawableRectangle bairectangle = new DrawableRectangle(left, top, right, bottom);
DrawableStrokeWidth strokeWidth = new DrawableStrokeWidth(1);
DrawableStrokeColor strokeColorBlack = new DrawableStrokeColor(new MagickColor("black"));
DrawableFillColor fillColorLime = new DrawableFillColor(new MagickColor("lime"));
image.Draw(strokeColorBlack, strokeWidth, fillColorLime, bairectangle);
.. logic ....
image.Settings.FontPointsize = 34;
tekst.Value = bai.getName();
tekst.X = new_bai_x;
tekst.Y = bsi_y;
image.Draw(tekst);
and so on and so on.
Coordinator
Apr 24, 2016 at 4:35 PM
Edited Apr 24, 2016 at 4:42 PM
The 'new Drawable' actions are executed in the Draw method. I just pass them directly as an argument instead of using a variable like you do. I am planning to add an extra syntax soon (https://magick.codeplex.com/workitem/1384) that should be something like this:
image.Draw(new Drawables()
    .FillColor(MagickColors.Transparent) // -fill none
    .StrokeColor(MagickColors.Black) // -stroke black
    .StrokeWidth(1) // -strokewidth 1
  );
And it is better to be using the 'using thing'. Magick.NET uses unmanaged memory and the using makes sure it is cleaned up properly.
Apr 24, 2016 at 5:07 PM
I am processing input data and whilst I am doing that I am drawing the necessary boxes and texts while calculating where they need to come.
By using the using statement would I then have to calculate everything upfront and code it in a single using?

Example generated picture.
Image

I know what GC is but my program runs for a few seconds only, not 24x7 so I don't need to care........... :-)
And ofcourse limited programming skills....
Coordinator
Apr 24, 2016 at 7:45 PM
You can call Draw on the same image multiple times and there is no problem to do your logic inside a using block.
Apr 24, 2016 at 9:04 PM
Edited Apr 24, 2016 at 9:06 PM
dlemstra wrote:
You can call Draw on the same image multiple times and there is no problem to do your logic inside a using block.
ok, i'll take a look at my code and ponder, ponder and improve! Thanks!
I have already removed my starting empty png :-).