Default to 800x600 transparent image output
This commit is contained in:
parent
f8fc3518dd
commit
6e04286cc2
@ -40,4 +40,6 @@ struct Color
|
|||||||
{
|
{
|
||||||
return cast(ubyte)(0xFF * v);
|
return cast(ubyte)(0xFF * v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static immutable Color TRANSPARENT = Color(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,27 @@
|
|||||||
import fart.png;
|
module fart.main;
|
||||||
|
|
||||||
|
import fart.png;
|
||||||
|
import fart.color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main program entry point.
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
* Program arguments.
|
||||||
|
*/
|
||||||
int main(string[] args)
|
int main(string[] args)
|
||||||
{
|
{
|
||||||
png_test();
|
size_t width = 800;
|
||||||
|
size_t height = 600;
|
||||||
|
string output_filename = "out.png";
|
||||||
|
Color[] pixels = [];
|
||||||
|
for (size_t y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
for (size_t x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
pixels ~= Color.TRANSPARENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write_png(output_filename, width, height, pixels);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
module fart.png;
|
module fart.png;
|
||||||
|
|
||||||
import std.zlib;
|
import std.zlib;
|
||||||
import std.math;
|
|
||||||
import std.digest;
|
import std.digest;
|
||||||
|
|
||||||
import fart.bfile;
|
import fart.bfile;
|
||||||
@ -9,8 +8,14 @@ import fart.crc32;
|
|||||||
import fart.hton;
|
import fart.hton;
|
||||||
import fart.color;
|
import fart.color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PNG file header.
|
||||||
|
*/
|
||||||
private immutable ubyte[] HEADER = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A];
|
private immutable ubyte[] HEADER = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PNG IHDR chunk.
|
||||||
|
*/
|
||||||
struct IHDR
|
struct IHDR
|
||||||
{
|
{
|
||||||
uint width;
|
uint width;
|
||||||
@ -22,10 +27,10 @@ struct IHDR
|
|||||||
ubyte interlace;
|
ubyte interlace;
|
||||||
ubyte[0] end;
|
ubyte[0] end;
|
||||||
|
|
||||||
this(uint width, uint height)
|
this(size_t width, size_t height)
|
||||||
{
|
{
|
||||||
this.width = htonl(width);
|
this.width = htonl(cast(uint)width);
|
||||||
this.height = htonl(height);
|
this.height = htonl(cast(uint)height);
|
||||||
this.bit_depth = 8;
|
this.bit_depth = 8;
|
||||||
this.color_type = 6;
|
this.color_type = 6;
|
||||||
this.compression = 0;
|
this.compression = 0;
|
||||||
@ -44,6 +49,9 @@ struct IHDR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PNG IDAT chunk.
|
||||||
|
*/
|
||||||
struct IDAT
|
struct IDAT
|
||||||
{
|
{
|
||||||
private const(ubyte)[] m_data;
|
private const(ubyte)[] m_data;
|
||||||
@ -64,6 +72,9 @@ struct IDAT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PNG IEND chunk.
|
||||||
|
*/
|
||||||
struct IEND
|
struct IEND
|
||||||
{
|
{
|
||||||
public const(void) * data()
|
public const(void) * data()
|
||||||
@ -77,6 +88,16 @@ struct IEND
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a PNG chunk to the output file.
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* Output file
|
||||||
|
* @param chunk_type
|
||||||
|
* Chunk type.
|
||||||
|
* @param chunk
|
||||||
|
* Chunk to write.
|
||||||
|
*/
|
||||||
private void write_chunk(Chunk)(BFile file, string chunk_type, Chunk chunk)
|
private void write_chunk(Chunk)(BFile file, string chunk_type, Chunk chunk)
|
||||||
{
|
{
|
||||||
size_t chunk_data_length = chunk.data_length();
|
size_t chunk_data_length = chunk.data_length();
|
||||||
@ -89,11 +110,24 @@ private void write_chunk(Chunk)(BFile file, string chunk_type, Chunk chunk)
|
|||||||
file.writeObject(crc_be32);
|
file.writeObject(crc_be32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write_png(string filename, uint width, uint height, const(Color)[] data)
|
/**
|
||||||
|
* Write a PNG image from the given metadata and pixel data.
|
||||||
|
*
|
||||||
|
* @param filename
|
||||||
|
* Name of file to write.
|
||||||
|
* @param width
|
||||||
|
* Width of image.
|
||||||
|
* @param height
|
||||||
|
* Height of image.
|
||||||
|
* @param data
|
||||||
|
* Pixel color data.
|
||||||
|
*/
|
||||||
|
public void write_png(string filename, size_t width, size_t height, const(Color)[] data)
|
||||||
{
|
{
|
||||||
if (data.length != width * height)
|
if (data.length != width * height)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Convert Color values to 32-bit RGBA values. */
|
||||||
ubyte[] pixel_data;
|
ubyte[] pixel_data;
|
||||||
size_t data_index;
|
size_t data_index;
|
||||||
for (size_t y = 0; y < height; y++)
|
for (size_t y = 0; y < height; y++)
|
||||||
@ -105,30 +139,20 @@ public void write_png(string filename, uint width, uint height, const(Color)[] d
|
|||||||
pixel_data ~= data[data_index++].rgba32();
|
pixel_data ~= data[data_index++].rgba32();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Open output file. */
|
||||||
BFile file = BFile(filename);
|
BFile file = BFile(filename);
|
||||||
|
/* Write PNG header. */
|
||||||
file.write(HEADER);
|
file.write(HEADER);
|
||||||
|
/* Write IHDR chunk. */
|
||||||
IHDR ihdr = IHDR(width, height);
|
IHDR ihdr = IHDR(width, height);
|
||||||
write_chunk(file, "IHDR", ihdr);
|
write_chunk(file, "IHDR", ihdr);
|
||||||
|
/* Write IDAT chunk. */
|
||||||
IDAT idat = IDAT(pixel_data);
|
IDAT idat = IDAT(pixel_data);
|
||||||
write_chunk(file, "IDAT", idat);
|
write_chunk(file, "IDAT", idat);
|
||||||
|
/* Write IEND chunk. */
|
||||||
IEND iend;
|
IEND iend;
|
||||||
write_chunk(file, "IEND", iend);
|
write_chunk(file, "IEND", iend);
|
||||||
|
/* Close output file. */
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void png_test()
|
|
||||||
{
|
|
||||||
Color[] pixel_data = [];
|
|
||||||
for (size_t y = 0; y < 500; y++)
|
|
||||||
{
|
|
||||||
for (size_t x = 0; x < 500; x++)
|
|
||||||
{
|
|
||||||
ubyte r = cast(ubyte)(x / 2);
|
|
||||||
ubyte g = 0x80;
|
|
||||||
ubyte b = cast(ubyte)((500 - y) / 2);
|
|
||||||
ubyte a = cast(ubyte)((abs(cast(int)x - 250) + abs(cast(int)y - 250)) / 2);
|
|
||||||
pixel_data ~= Color(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write_png("out.png", 500, 500, pixel_data);
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user