Pages

Drawing lines and polylines

I need to create a PNG file where lines are drawn on a background that could be of a solid color or transparent. It's an easy job, but it requires to use a few Magick++ classes. As we are going to see, the Image class has a central role in it.

Background color

There are many ways of creating a Magick++ Color. Actually, there are even many Magick++ Color flavors, rigorized as classes that all derives from Magick::Color. Here my requirements are not very demanding, so I can easily settle for using the base class, and just a couple of its constructors.

For simple standard colors, ImageMagick uses the X11 name convention, so that I can define a very light orange background in this way:
Magick::Color background("papaya whip");
A full list of X11 color names is on wikipedia.

We can specify the level of transparency of a color at its creation time, calling the Color constructor that expects in input red, green, blue, and alpha (AKA, its transparency) quantums. That's how I create a fully transparent color:
Magick::Color background(0, 0, 0, QuantumRange);
I have already written something about the relation about Quantum, QuantumRange and Imagick++ in a previous post, so here I just assume you know what I am talking about.
Being fully transparent, it doesn't matter the quantum level for the first three components. A fully transparent black (that the one I picked up) does not differ from any other fully transparent color.

Creating an image

Once I have a background color, I can create an 50x50 Image object in this way:
Magick::Image image(Magick::Geometry(50, 50), background);
It is usually a smart idea to specify just after creation which kind of image we are interested in:
image.magick("PNG");
Another common early setting is about the kind of stroke I want to use. Here I set its width and the line cap shape:
image.strokeWidth(4);
image.strokeLineCap(Magick::RoundCap);
Drawing lines

I am about to draw the red/blue asterisk on transparent background that you see here aside.

Firstly I draw the red X, than I switch to blue and I draw a plus. In both case, what I actually draw are simple lines, two red ones and two blue ones, with no relation one to the others. It is all pretty easy:
image.strokeColor(Magick::Color("red")); // 1
image.draw(Magick::DrawableLine(10, 10, 40, 40)); // 2
image.draw(Magick::DrawableLine(40, 10, 10, 40));

image.strokeColor(Magick::Color("blue")); // 3
image.draw(Magick::DrawableLine(5, 25, 45, 25));
image.draw(Magick::DrawableLine(25, 5, 25, 45));
1. Select the red color.
2. Draw a first line from (10, 10) to (40, 40), then a second one from (40, 10) to (10, 40).
3. Then I switch to blue, and I draw the other couple of lines.

Drawing polylines

Things get a bit more complicated in case of polylines. If a line has just a beginning and an end, a polyline is defined by a number of points, each point describing an object vertex. I need to call the Image::draw() method on the entire collection of points. To do that, we use a STL list container parametrized for the Magick Coordinate class.

Before filling the list, I set a few other stroke options, and the filling color. More details below the code:
image.strokeAntiAlias(true); // 1
image.strokeLineJoin(Magick::RoundJoin); // 2
image.strokeColor(Magick::Color("red")); // 3
image.fillColor(background); // 4

std::list<Magick::Coordinate> line; // 5
line.push_back(Magick::Coordinate(11,4));
line.push_back(Magick::Coordinate(41,23));
line.push_back(Magick::Coordinate(27,42));
line.push_back(Magick::Coordinate(59,91));

image.draw(Magick::DrawablePolyline(line)); // 6
1. Activate the anti-aliasing. This means that Magick will do its best to avoid jaggies, trying to smoothing the drawing.
2. I say to Magick to round the join in the connection between parts of the polyline.
3. The foreground color is the bright standard X11 red.
4. If I don't say to Magick to use a specific color as filler, the stroke color will be used. Not what I want to get here.
5. Instantiate a list of Coordinates, and fill it with the points I need.
6. And finally, I convert the list in a drawable polyline, and I draw it.

Saving the image in a file

We need a last step, writing the image to a file:
image.write("/tmp/test.png");
Exceptions

The Magick++ exceptions are derived by the STL exception. So you could try/catch your Magick++ code just for the generic standard exception. If you want finer management you can add more catch blocks to your code. For instance, here I was interested in giving a specific message for the ErrorBlob exception:
try
{
  // Magick++ code goes here
}
catch(Magick::ErrorBlob& ex)
{
  std::cout << "Magick ErrorBlob: " << ex.what() << std::endl;
}
catch(std::exception& ex)
{
  std::cout << "Error: " << ex.what() << std::endl;
}

Go to the full post

ZeroMQ and open source

Pieter Hintjens has uploaded on vimeo the talk on ZeroMQ and open source he gave at CERN on 27 June 2013. I warmly suggest you to watch it. It is longish, but it is worthy.


He says ZeroMQ is designed around a protocol, that originally was just about framing the message sent around, and then it expanded adding versioning information and security.

Than he says how important are patterns (Pub-Sub, Req-Rep, Pipeline ...) that are wrapped in sockets, giving an easy to use approach, and robustness, to the framework.

Bindings are important, because they make ZeroMq available on many different platforms, and they help building a strong programming community. As it helps the licensing policy, designed expressly to take advantage of the open source market.

The ZeroMQ's growth is based on contributions, anyone could contribute with its own code (through github pull request). But you should not break the API. The process is based on small changes, that should lead to a smooth migration to new versions.

A strong point is that people are more important than the code. The idea is that a project is a way of organizing people around a problem, so that they can interact to find solutions. Problems are important, because they lead to improvement.

Go to the full post

A Quantum of ImageMagick

ImageMagick defines Quantum as the base type to represent color. To make the framework flexible, a constant named MAGICKCORE_QUANTUM_DEPTH (or its deprecated alias, QuantumDepth) determines the number of bits in a Quantum. It gets a value among 8, 16, 32, and 64. An higher depth gives better precision, and it is paid in term of heavier resource consumption.

In the current ImageMagick version, MAGICKCORE_QUANTUM_DEPTH is defaulted to 16, you should see it in the magick-type.h include file. This lead also to a type definition for Quantum as unsigned short.

In this context, QuantumRange, the highest value that could be assigned to a Quantum variable (it has a deprecated alias, too, MaxRGB), is defined as a symbolic constant in this way:
#define QuantumRange  ((Quantum) 65535)
When working in C++ through the Magick++ library, this could lead to an unfriendly behavior.

Say that we need a Quantum variable, and we want to initialize it to QuantumRange. You are probably bound to write a line of code like this:
Magick::Quantum quantum = QuantumRange;
Alas, this could not work. As we have seen, the value of QuantumRange is casted to Quantum in its definition. This works fine when developing in C, but when we are writing code through Magick++, we need to qualify each Magick type with its proper namespace.
The compiler needs to know where to look for the Quantum definition, otherwise we'll get a compile error like "'Quantum' was not declared in this scope".

We have at least a couple of alternative solutions to this issue:
using namespace Magick;

// ...
Magick::Quantum quantum = QuantumRange;
All the code between the using directive and the end of file would have access to the the Magick namespace. A bit dirty, isn't it?
Magick::Quantum quantum;
{
  using namespace Magick;
  quantum = QuantumRange;
}
Split declaration and definition of the variable, and perform the second in a tiny scope where we use the namespace directive. Cleaner, but more verbose, too.

Go to the full post