Drawing text on an angle
Posted: 2011-12-15T07:57:05-07:00
I am totally missing something. All I am trying to do is draw some text between 2 points. Quite often, this will be on an angle. My Google-foo has been failing me on this...
I know how to do this in GD (call gdImageStringFT) and how to do this in cairo (using pango), but I can not seem to figure it out in Magick++.
Based on the headers, I think I need to use some combination of transformOrigin/transformRotation/transformReset, but I can't seem to figure it out.
I wrote this little test program that creates 2 identical images, one with Magick++ and one with GD. I think the problem is that after I do the transformRotation, my coordinate system is wrong......
Any help would be greatly appreciated.....
- Brian
I know how to do this in GD (call gdImageStringFT) and how to do this in cairo (using pango), but I can not seem to figure it out in Magick++.
Based on the headers, I think I need to use some combination of transformOrigin/transformRotation/transformReset, but I can't seem to figure it out.
I wrote this little test program that creates 2 identical images, one with Magick++ and one with GD. I think the problem is that after I do the transformRotation, my coordinate system is wrong......
Code: Select all
#include <Magick++.h>
#include <gd.h>
#include <cstring>
#include <fstream>
#include <math.h>
gdImagePtr gdimage;
Magick::Image mimage;
char* tmpFont = "/usr/share/fonts/type1/gsfonts/n022003l.pfb";
int fontSize = 10;
double angleBetweenTwoPoints(double x1, double y1, double x2, double y2)
{
double dx = x2 - x1;
double dy = y2 - y1;
double angle = 0.;
if (dx >= -3 && dx <= 3)
dx = 0;
if (dy >= -3 && dy <= 3)
dy = 0;
if (dx != 0 && dy != 0)
angle = atan(fabs(dy) / fabs(dx));
if (dx == 0 && dy < 0)
angle = M_PI_2l;
else if (dx == 0 && dy > 0)
angle = M_PIl + M_PI_2l;
else if (dy == 0 && dx > 0)
angle = 0;
else if (dy == 0 && dx < 0)
angle = M_PIl;
else if (x2 > x1 && y2 > y1)
angle = M_PIl + M_PIl - angle;
else if (x2 < x1 && y2 < y1)
angle += M_PI_2l;
else if (x2 < x1 && y2 > y1)
angle += M_PIl;
return angle;
}
void draw(double x1, double y1, double x2, double y2, int red, int green, int blue, char* str)
{
double angle = angleBetweenTwoPoints(x1, y1, x2, y2);
int style[1], lineColor;
// Define GD color
lineColor = gdImageColorAllocate(gdimage, red, green, blue);
style[0] = lineColor;
gdImageSetStyle(gdimage, style, 1);
// Define Magick color
mimage.strokeColor(Magick::ColorRGB(red / 255.0, green / 255.0, blue / 255.0));
// Draw GD line
gdImageLine(gdimage, x1, y1, x2, y2, gdStyled);
// Draw Magick line
mimage.draw(Magick::DrawableLine(x1, y1, x2, y2));
// Draw the GD string
gdImageStringFT(gdimage, NULL, lineColor, tmpFont, fontSize, angle, ((x2 + x1) / 2), ((y2 + y1) / 2), str);
// Draw the Magick string
mimage.transformRotation((angle/ M_PI) * 180.0); // angle is in radians
mimage.draw(Magick::DrawableText(((x2 + x1) / 2), ((y2 + y1) / 2), str));
mimage.transformReset();
}
int main(int, char**)
{
///////////////////////////////////////
// Magick image
//
mimage = Magick::Image(Magick::Geometry(256, 256), Magick::ColorRGB(250 / 255.0, 240 / 255.0, 230 / 255.0));
mimage.magick("png");
mimage.font(tmpFont);
mimage.fontPointsize(fontSize);
// Magick image
//
///////////////////////////////////////
///////////////////////////////////////
// GD image
//
gdimage = gdImageCreateTrueColor(256, 256);
// first color
int lineColor = gdImageColorAllocate(gdimage, 250, 240, 230);
gdPoint* points = new gdPoint[4];
points[0].x = 255;
points[0].y = 0;
points[1].x = 255;
points[1].y = 255;
points[2].x = 0;
points[2].y = 255;
points[3].x = 0;
points[3].y = 0;
gdImageFilledPolygon(gdimage, points, 4, lineColor );
delete[] points;
// GD image
//
///////////////////////////////////////
draw(30, 30, 255, 30, 255, 0, 0, "horz");
draw(30, 30, 30, 255, 255, 0, 0, "vert");
draw(0, 0, 127, 127, 0, 0, 255, "one");
draw(127, 127, 255, 0, 0, 255, 0, "two");
draw(0, 255, 127, 127, 255, 0, 255, "three");
draw(127, 127, 255, 255, 0, 255, 255, "four");
draw(255, 30, 30, 30, 255, 0, 0, "rev-horz");
draw(30, 255, 30, 30, 255, 0, 0, "rev-vert");
draw(127, 127, 0, 0, 0, 0, 255, "rev-one");
draw(255, 0, 127, 127, 0, 255, 0, "rev-two");
draw(127, 127, 0, 255, 255, 0, 255, "rev-three");
draw(255, 255, 127, 127, 0, 255, 255, "rev-four");
int imageSize;
void* imagePtr = gdImagePngPtr(gdimage, &imageSize);
std::ofstream ofs("gd.png");
ofs.write(static_cast<const char *>(imagePtr), imageSize);
ofs.close();
mimage.write("magick.png");
}
- Brian