1 module nudsfml.graphics.image; 2 3 import bindbc.sfml.graphics; 4 5 import nudsfml.graphics.color; 6 import nudsfml.graphics.rect; 7 import nudsfml.system.vector2; 8 import nudsfml.system.inputstream; 9 10 class Image { 11 sfImage* sfPtr = null; 12 /// Default constructor. 13 this() { 14 sfPtr = sfImage_create(0,0); 15 } 16 17 package this(sfImage* image){ 18 sfPtr = image; 19 } 20 21 /// Destructor. 22 ~this() { 23 if(sfPtr != null){ 24 sfImage_destroy(sfPtr); 25 } 26 } 27 28 /** 29 * Create the image and fill it with a unique color. 30 * 31 * Params: 32 * width = Width of the image 33 * height = Height of the image 34 * color = Fill color 35 * 36 */ 37 void create(uint width, uint height, Color color) { 38 sfColor c = fromColor(color); 39 if(sfPtr !is null) { 40 sfImage_destroy(sfPtr); 41 } 42 sfPtr = sfImage_createFromColor(width, height,c); 43 } 44 45 /** 46 * Create the image from an array of pixels. 47 * 48 * The pixel array is assumed to contain 32-bits RGBA pixels, and have the 49 * given width and height. If not, this is an undefined behaviour. If pixels 50 * is null, an empty image is created. 51 * 52 * Params: 53 * width = Width of the image 54 * height = Height of the image 55 * pixels = Array of pixels to copy to the image 56 * 57 */ 58 void create(uint width, uint height, const(ubyte)[] pixels) { 59 if (sfPtr !is null) 60 sfImage_destroy(sfPtr); 61 sfPtr = sfImage_createFromPixels(width, height,pixels.ptr); 62 } 63 64 /** 65 * Load the image from a file on disk. 66 * 67 * The supported image formats are bmp, png, tga, jpg, gif, psd, hdr and 68 * pic. Some format options are not supported, like progressive jpeg. If 69 * this function fails, the image is left unchanged. 70 * 71 * Params: 72 * filename = Path of the image file to load 73 * 74 * Returns: true if loading succeeded, false if it failed 75 */ 76 bool loadFromFile(const(char)[] filename) { 77 import std.string; 78 if(sfPtr !is null){ 79 sfImage_destroy(sfPtr); 80 } 81 sfPtr = sfImage_createFromFile(filename.toStringz); 82 return sfPtr !is null; 83 } 84 85 /** 86 * Load the image from a file in memory. 87 * 88 * The supported image formats are bmp, png, tga, jpg, gif, psd, hdr and 89 * pic. Some format options are not supported, like progressive jpeg. If 90 * this function fails, the image is left unchanged. 91 * 92 * Params: 93 * data = Data file in memory to load 94 * 95 * Returns: true if loading succeeded, false if it failed 96 */ 97 bool loadFromMemory(const(void)[] data) { 98 if(sfPtr !is null){ 99 sfImage_destroy(sfPtr); 100 } 101 sfPtr = sfImage_createFromMemory(data.ptr, data.length); 102 return sfPtr !is null; 103 } 104 105 /** 106 * Get the color of a pixel 107 * 108 * This function doesn't check the validity of the pixel coordinates; using 109 * out-of-range values will result in an undefined behaviour. 110 * 111 * Params: 112 * x = X coordinate of the pixel to get 113 * y = Y coordinate of the pixel to get 114 * 115 * Returns: Color of the pixel at coordinates (x, y) 116 */ 117 Color getPixel(uint x, uint y) const { 118 import std.conv; 119 sfColor c = sfImage_getPixel(sfPtr, x,y); 120 Color temp; 121 temp.r = c.r.to!ubyte; 122 temp.g = c.g.to!ubyte; 123 temp.b = c.b.to!ubyte; 124 temp.a = c.a.to!ubyte; 125 return temp; 126 } 127 128 /** 129 * Get the read-only array of pixels that make up the image. 130 * 131 * The returned value points to an array of RGBA pixels made of 8 bits 132 * integers components. The size of the array is: 133 * `width * height * 4 (getSize().x * getSize().y * 4)`. 134 * 135 * Warning: the returned slice may become invalid if you modify the image, 136 * so you should never store it for too long. 137 * 138 * Returns: Read-only array of pixels that make up the image. 139 */ 140 const(ubyte)[] getPixelArray() const { 141 import std.stdio; 142 Vector2u size = getSize(); 143 int length = size.x * size.y * 4; 144 145 if(length!=0) { 146 return sfImage_getPixelsPtr(sfPtr)[0..length]; 147 } else { 148 writeln("Trying to access the pixels of an empty image"); 149 return []; 150 } 151 } 152 153 /** 154 * Return the size (width and height) of the image. 155 * 156 * Returns: Size of the image, in pixels. 157 */ 158 Vector2u getSize() const { 159 auto v = sfImage_getSize(sfPtr); 160 Vector2u temp = Vector2u(v.x,v.y); 161 return temp; 162 } 163 164 /** 165 * Return the size (width and height) of the image. 166 * 167 * Returns: Size of the image, in pixels. 168 */ 169 Vector2u size() const { 170 auto v = sfImage_getSize(sfPtr); 171 Vector2u temp = Vector2u(v.x,v.y); 172 return temp; 173 } 174 175 176 /** 177 * Change the color of a pixel. 178 * 179 * This function doesn't check the validity of the pixel coordinates, using 180 * out-of-range values will result in an undefined behaviour. 181 * 182 * Params: 183 * x = X coordinate of pixel to change 184 * y = Y coordinate of pixel to change 185 * color = New color of the pixel 186 */ 187 void setPixel(uint x, uint y, Color color) { 188 sfColor c = fromColor(color); 189 sfImage_setPixel(sfPtr, x,y,c); 190 } 191 192 /** 193 * Copy pixels from another image onto this one. 194 * 195 * This function does a slow pixel copy and should not be used intensively. 196 * It can be used to prepare a complex static image from several others, but 197 * if you need this kind of feature in real-time you'd better use 198 * RenderTexture. 199 * 200 * If sourceRect is empty, the whole image is copied. If applyAlpha is set 201 * to true, the transparency of source pixels is applied. If it is false, 202 * the pixels are copied unchanged with their alpha value. 203 * 204 * Params: 205 * source = Source image to copy 206 * destX = X coordinate of the destination position 207 * destY = Y coordinate of the destination position 208 * sourceRect = Sub-rectangle of the source image to copy 209 * applyAlpha = Should the copy take the source transparency into account? 210 */ 211 void copyImage(const(Image) source, uint destX, uint destY, IntRect sourceRect = IntRect(0,0,0,0), bool applyAlpha = false){ 212 sfIntRect sourcerect; 213 214 sourcerect.left = sourceRect.left; 215 sourcerect.top = sourceRect.top; 216 sourcerect.width = sourceRect.width; 217 sourcerect.height = sourceRect.height; 218 219 sfImage_copyImage(sfPtr, source.sfPtr, destX, destY,sourcerect, applyAlpha); 220 } 221 222 /** 223 * Create a transparency mask from a specified color-key. 224 * 225 * This function sets the alpha value of every pixel matching the given 226 * color to alpha (0 by default) so that they become transparent. 227 * 228 * Params: 229 * maskColor = Color to make transparent 230 * alpha = Alpha value to assign to transparent pixels 231 */ 232 void createMaskFromColor(Color maskColor, ubyte alpha = 0) { 233 sfColor c = fromColor(maskColor); 234 sfImage_createMaskFromColor(sfPtr,c, alpha); 235 } 236 237 /// Create a copy of the Image. 238 @property Image dup() const { 239 return new Image(sfImage_copy(sfPtr)); 240 } 241 242 /// Flip the image horizontally (left <-> right) 243 void flipHorizontally(){ 244 sfImage_flipHorizontally(sfPtr); 245 } 246 247 /// Flip the image vertically (top <-> bottom) 248 void flipVertically() { 249 sfImage_flipVertically(sfPtr); 250 } 251 252 /** 253 * Save the image to a file on disk. 254 * 255 * The format of the image is automatically deduced from the extension. The 256 * supported image formats are bmp, png, tga and jpg. The destination file 257 * is overwritten if it already exists. This function fails if the image is 258 * empty. 259 * 260 * Params: 261 * filename = Path of the file to save 262 * 263 * Returns: true if saving was successful 264 */ 265 bool saveToFile(const(char)[] filename) const{ 266 import std.string; 267 auto f = filename.toStringz; 268 return sfImage_saveToFile(sfPtr, f)!=0; 269 } 270 }