implement drawCharacter function

This commit is contained in:
Emil Lerch 2023-03-29 17:58:24 -07:00
parent 8b22eadc4f
commit 60098caf01
Signed by: lobo
GPG Key ID: A7B62D657EF764F8
2 changed files with 73 additions and 63 deletions

View File

@ -57,7 +57,7 @@ fn make(step: *std.build.Step, _: *std.Progress.Node) !void {
}); });
defer file.close(); defer file.close();
const writer = file.writer(); const writer = file.writer();
try writer.print("const chars = [_][]u8 {{\n", .{}); try writer.print("pub const chars = &[_][]const u8{{\n", .{});
for (0..32) |_| { for (0..32) |_| {
try writer.print(" \"\",\n", .{}); try writer.print(" \"\",\n", .{});

View File

@ -220,7 +220,6 @@ fn convertImage(alloc: std.mem.Allocator, filename: [:0]u8, pixels: *[WIDTH * HE
defer { defer {
if (mw) |w| mw = c.DestroyMagickWand(w); if (mw) |w| mw = c.DestroyMagickWand(w);
} }
var merged: ?*c.MagickWand = undefined;
// Reading an image into ImageMagick is problematic if it isn't a bmp // Reading an image into ImageMagick is problematic if it isn't a bmp
// as the library needs a bunch of dependencies available // as the library needs a bunch of dependencies available
@ -276,20 +275,64 @@ fn convertImage(alloc: std.mem.Allocator, filename: [:0]u8, pixels: *[WIDTH * HE
if (status == c.MagickFalse) if (status == c.MagickFalse)
return error.CouldNotSetExtent; return error.CouldNotSetExtent;
// At this point, we will add our text. This needs a whole lot more than this, mw = try drawCharacter(
// but let's get started mw.?,
{ '4',
-5 * 3,
-8,
);
mw = try drawCharacter(
mw.?,
'2',
-5 * 4,
-8,
);
// We make the image monochrome by quantizing the image with 2 colors in the
// gray colorspace. See:
// https://www.imagemagick.org/Usage/quantize/#monochrome
// and
// https://stackoverflow.com/questions/18267432/using-the-c-api-for-imagemagick-on-iphone-to-convert-to-monochrome
//
// We do this at the end so we have pure black and white. Otherwise the
// resizing oprations will generate some greyscale that we don't want
status = c.MagickQuantizeImage(mw, // MagickWand
2, // Target number colors
c.GRAYColorspace, // Colorspace
1, // Optimal depth
c.MagickTrue, // Dither
c.MagickFalse // Quantization error
);
if (status == c.MagickFalse)
return error.CouldNotQuantizeImage;
status = c.MagickExportImagePixels(mw, 0, 0, WIDTH, HEIGHT, "I", c.CharPixel, @ptrCast(*anyopaque, pixels));
if (status == c.MagickFalse)
return error.CouldNotExportImage;
for (0..WIDTH * HEIGHT) |i| {
switch (pixels[i]) {
0x00 => pixels[i] = 0xFF,
0xFF => pixels[i] = 0x00,
else => {},
}
}
}
fn drawCharacter(mw: ?*c.MagickWand, char: u8, x: isize, y: isize) !?*c.MagickWand {
// Create a second wand. Does this need to exist after the block? // Create a second wand. Does this need to exist after the block?
var cw = c.NewMagickWand(); var cw = c.NewMagickWand();
defer { defer {
if (cw) |dw| cw = c.DestroyMagickWand(dw); if (cw) |dw| cw = c.DestroyMagickWand(dw);
if (merged) |mergeme| { // if (merged) |mergeme| {
_ = c.DestroyMagickWand(mw); // _ = c.DestroyMagickWand(mw);
mw = mergeme; // mw = mergeme;
// }
} }
} const image_char = chars[char];
const characters = @embedFile("images/test.bmp"); if (image_char.len == 0) return error.CharacterNotSupported;
status = c.MagickReadImageBlob(cw, characters, characters.len); var status = c.MagickReadImageBlob(cw, @ptrCast(?*const anyopaque, image_char), image_char.len);
if (status == c.MagickFalse) unreachable; // Something is terribly wrong if this fails if (status == c.MagickFalse) unreachable; // Something is terribly wrong if this fails
// For character placement, we need to set the image to the correct // For character placement, we need to set the image to the correct
@ -314,10 +357,8 @@ fn convertImage(alloc: std.mem.Allocator, filename: [:0]u8, pixels: *[WIDTH * HE
cw, cw,
WIDTH, WIDTH,
HEIGHT, HEIGHT,
-6 * 8, x,
-8, y,
// -@intCast(isize, (WIDTH - resize_dimensions.width) / 2),
// -@intCast(isize, (HEIGHT - resize_dimensions.height) / 2),
); );
if (status == c.MagickFalse) if (status == c.MagickFalse)
return error.CouldNotSetExtent; return error.CouldNotSetExtent;
@ -331,41 +372,10 @@ fn convertImage(alloc: std.mem.Allocator, filename: [:0]u8, pixels: *[WIDTH * HE
// I this only works with two images... // I this only works with two images...
// c.MagickResetIterator(mw); // c.MagickResetIterator(mw);
c.MagickSetFirstIterator(mw); c.MagickSetFirstIterator(mw);
merged = c.MagickMergeImageLayers(mw, c.FlattenLayer); defer {
// merged = c.MagickMergeImageLayers(mw, c.CompositeLayer); if (mw) |w| _ = c.DestroyMagickWand(w);
// if (status == c.MagickFalse) return error.CouldNotFlattenImage;
}
// We make the image monochrome by quantizing the image with 2 colors in the
// gray colorspace. See:
// https://www.imagemagick.org/Usage/quantize/#monochrome
// and
// https://stackoverflow.com/questions/18267432/using-the-c-api-for-imagemagick-on-iphone-to-convert-to-monochrome
//
// We do this at the end so we have pure black and white. Otherwise the
// resizing oprations will generate some greyscale that we don't want
status = c.MagickQuantizeImage(merged, // MagickWand
2, // Target number colors
c.GRAYColorspace, // Colorspace
1, // Optimal depth
c.MagickTrue, // Dither
c.MagickFalse // Quantization error
);
if (status == c.MagickFalse)
return error.CouldNotQuantizeImage;
status = c.MagickExportImagePixels(merged, 0, 0, WIDTH, HEIGHT, "I", c.CharPixel, @ptrCast(*anyopaque, pixels));
if (status == c.MagickFalse)
return error.CouldNotExportImage;
for (0..WIDTH * HEIGHT) |i| {
switch (pixels[i]) {
0x00 => pixels[i] = 0xFF,
0xFF => pixels[i] = 0x00,
else => {},
}
} }
return c.MagickMergeImageLayers(mw, c.FlattenLayer);
} }
const Dimensions = struct { const Dimensions = struct {