1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
//! Class for loading, manipulating and saving images.
const sf = struct {
pub usingnamespace @import("../sfml.zig");
pub usingnamespace sf.system;
pub usingnamespace sf.graphics;
};
const std = @import("std");
const assert = std.debug.assert;
const Image = @This();
// Constructor/destructor
/// Creates a new image
pub fn create(size: sf.Vector2u, color: sf.Color) !Image {
var img = sf.c.sfImage_createFromColor(size.x, size.y, color.toCSFML());
if (img == null)
return sf.Error.nullptrUnknownReason;
return Image{ .ptr = img.? };
}
/// Creates an image from a pixel array
pub fn createFromPixels(size: sf.Vector2u, pixels: []const sf.Color) !Image {
// Check if there is enough data
if (pixels.len < size.x * size.y)
return sf.Error.notEnoughData;
var img = sf.c.sfImage_createFromPixels(size.x, size.y, @ptrCast([*]const u8, pixels.ptr));
if (img == null)
return sf.Error.nullptrUnknownReason;
return Image{ .ptr = img.? };
}
/// Loads an image from a file
pub fn createFromFile(path: [:0]const u8) !Image {
var img = sf.c.sfImage_createFromFile(path);
if (img == null)
return sf.Error.resourceLoadingError;
return Image{ .ptr = img.? };
}
/// Destroys an image
pub fn destroy(self: Image) void {
sf.c.sfImage_destroy(self.ptr);
}
// Save an image to a file
pub fn saveToFile(self: Image, path: [:0]const u8) !void {
if (sf.c.sfImage_saveToFile(self.ptr, path) != 1)
return sf.Error.savingInFileFailed;
}
// Getters/setters
/// Gets a pixel from this image (bounds are only checked in an assertion)
pub fn getPixel(self: Image, pixel_pos: sf.Vector2u) sf.Color {
const size = self.getSize();
assert(pixel_pos.x < size.x and pixel_pos.y < size.y);
return sf.Color.fromCSFML(sf.c.sfImage_getPixel(self.ptr, pixel_pos.x, pixel_pos.y));
}
/// Sets a pixel on this image (bounds are only checked in an assertion)
pub fn setPixel(self: Image, pixel_pos: sf.Vector2u, color: sf.Color) void {
const size = self.getSize();
assert(pixel_pos.x < size.x and pixel_pos.y < size.y);
sf.c.sfImage_setPixel(self.ptr, pixel_pos.x, pixel_pos.y, color.toCSFML());
}
/// Gets the size of this image
pub fn getSize(self: Image) sf.Vector2u {
const size = sf.c.sfImage_getSize(self.ptr);
return sf.Vector2u{ .x = size.x, .y = size.y };
}
/// Pointer to the csfml texture
ptr: *sf.c.sfImage,
test "image: sane getters and setters" {
const tst = std.testing;
const allocator = std.heap.page_allocator;
var pixel_data = try allocator.alloc(sf.Color, 30);
defer allocator.free(pixel_data);
for (pixel_data) |*c, i| {
c.* = sf.Color.fromHSVA(@intToFloat(f32, i) / 30 * 360, 100, 100, 1);
}
var img = try Image.createFromPixels(.{ .x = 5, .y = 6 }, pixel_data);
defer img.destroy();
try tst.expectEqual(sf.Vector2u{ .x = 5, .y = 6 }, img.getSize());
img.setPixel(.{ .x = 1, .y = 2 }, sf.Color.Cyan);
try tst.expectEqual(sf.Color.Cyan, img.getPixel(.{ .x = 1, .y = 2 }));
var tex = try sf.Texture.createFromImage(img, null);
defer tex.destroy();
}
|