Skip to content

Commit ae7ad21

Browse files
committed
feat: add ostream support.
1 parent 10f8b53 commit ae7ad21

File tree

3 files changed

+48
-32
lines changed

3 files changed

+48
-32
lines changed

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,22 @@ qr.disable_quiet_zone();
7171
- PNG
7272
- TGA
7373
- BMP
74+
- ANSI
7475

75-
##### paint(format, filename, enlarge)
76+
##### paint(format, filename/ostream, enlarge)
7677

7778
- the image size = dimension * enlarge x dimension * enlarge
7879

79-
##### paint(format, filename, width, height)
80+
##### paint(format, filename/ostream, width, height)
8081

8182
- the image size = width x height
8283

8384
```c++
84-
qr.generate().paint(pic::Format::BMP, "example.bmp", 10);
85-
qr.generate().paint(pic::Format::PNG, "example.bmp", 1024, 1024);
85+
auto pic = qr.generate();
86+
pic.paint(pic::Format::BMP, "example.bmp", 10);
87+
std::ofstream fs("examples/example2.png", std::ios::binary | std::ios::out);
88+
pic.paint(pic::Format::PNG, fs, 1024, 1024);
89+
fs.close();
8690
```
8791
8892
For more examples, see [here](examples/src/main.cpp)

examples/src/main.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,13 @@ int main()
5555
* Output
5656
*/
5757
// func output pic
58-
// - paint(fmt, path, enlarge) -> (QR dimension * enlarge) * (QR dimension * enlarge)
59-
// - paint(fmt, path, width, height) -> width * height
58+
// - paint(fmt, path/ostream, enlarge) -> (QR dimension * enlarge) * (QR dimension * enlarge)
59+
// - paint(fmt, path/ostream, width, height) -> width * height
6060
// 1 PNG
6161
qr1.generate().paint(pic::Format::PNG, "examples/example1.png", 10);
62-
qr2.generate().paint(pic::Format::PNG, "examples/example2.png", 100);
62+
std::ofstream fs("examples/example2.png", std::ios::binary | std::ios::out);
63+
qr2.generate().paint(pic::Format::PNG, fs, 100);
64+
fs.close();
6365
// 2 JPG
6466
auto qr = qr3.generate();
6567
qr.paint(pic::Format::JPG, "examples/example3.jpg", 512, 512);

include/opqr/oppic.hpp

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
#include "operror.hpp"
1818

1919
#define STB_IMAGE_IMPLEMENTATION
20-
//#define STBI_ONLY_PNM
20+
#define STBI_ONLY_PNM
21+
#define STBI_ONLY_PNG
22+
2123
#include "stb/stb_image.h"
2224

2325
#define STB_IMAGE_WRITE_IMPLEMENTATION
@@ -50,12 +52,26 @@ namespace opqr::pic
5052
};
5153
private:
5254
std::vector<std::vector<bool>> data;
53-
55+
5456
public:
5557
Pic(std::vector<std::vector<bool>> data_)
5658
: data(std::move(data_)) {}
57-
59+
5860
void paint(Format fmt, const std::string &path, size_t width, size_t height) const
61+
{
62+
std::ofstream fs(path, std::ios::binary | std::ios::out);
63+
paint(fmt, fs, width, height);
64+
fs.close();
65+
}
66+
67+
void paint(Format fmt, const std::string &path, size_t enlarge) const
68+
{
69+
std::ofstream fs(path, std::ios::binary | std::ios::out);
70+
paint(fmt, fs, enlarge);
71+
fs.close();
72+
}
73+
74+
void paint(Format fmt, std::ostream &os, size_t width, size_t height) const
5975
{
6076
if (fmt == Format::ANSI256)
6177
{
@@ -75,25 +91,10 @@ namespace opqr::pic
7591
pic.data = out;
7692
pic.width = static_cast<int>(width);
7793
pic.height = static_cast<int>(height);
78-
write_pic(fmt, path, pic);
94+
write_pic(fmt, os, pic);
7995
stbi_image_free(out);
8096
}
8197

82-
void paint(Format fmt, const std::string &path, size_t enlarge = 1) const
83-
{
84-
if (enlarge == 0)
85-
{
86-
throw error::Error(OPQR_ERROR_LOCATION, __func__, "enlarge must >= 1.");
87-
}
88-
if (fmt == Format::ANSI256)
89-
{
90-
throw error::Error(OPQR_ERROR_LOCATION, __func__, "Unsupported format(ANSI256) when writing to path");
91-
}
92-
auto pic = load_pic(enlarge);
93-
write_pic(fmt, path, pic);
94-
stbi_image_free(pic.data);
95-
}
96-
9798
void paint(Format fmt, std::ostream &os, size_t enlarge = 1) const
9899
{
99100
if (enlarge == 0)
@@ -126,28 +127,37 @@ namespace opqr::pic
126127
}
127128
break;
128129
default:
129-
throw error::Error(OPQR_ERROR_LOCATION, __func__, "Unsupported format when writing to a stream");
130+
{
131+
auto pic = load_pic(enlarge);
132+
write_pic(fmt, os, pic);
133+
stbi_image_free(pic.data);
134+
}
130135
break;
131136
}
132137
}
133138

134139
private:
135-
void write_pic(Format fmt, const std::string &path, StbData data) const
140+
void write_pic(Format fmt, std::ostream &os, StbData data) const
136141
{
137142
int ret = 0;
143+
auto func = [](void *context, void *data, int size)
144+
{
145+
auto osptr = reinterpret_cast<std::ostream *>(context);
146+
osptr->write(reinterpret_cast<char *>(data), size);
147+
};
138148
switch (fmt)
139149
{
140150
case Format::JPG:
141-
ret = stbi_write_jpg(path.c_str(), data.width, data.height, data.channels, data.data, 100);
151+
ret = stbi_write_jpg_to_func(func, &os, data.width, data.height, data.channels, data.data, 100);
142152
break;
143153
case Format::PNG:
144-
ret = stbi_write_png(path.c_str(), data.width, data.height, data.channels, data.data, 0);
154+
ret = stbi_write_png_to_func(func, &os, data.width, data.height, data.channels, data.data, 0);
145155
break;
146156
case Format::TGA:
147-
ret = stbi_write_tga(path.c_str(), data.width, data.height, data.channels, data.data);
157+
ret = stbi_write_tga_to_func(func, &os, data.width, data.height, data.channels, data.data);
148158
break;
149159
case Format::BMP:
150-
ret = stbi_write_bmp(path.c_str(), data.width, data.height, data.channels, data.data);
160+
ret = stbi_write_bmp_to_func(func, &os, data.width, data.height, data.channels, data.data);
151161
break;
152162
}
153163
if (ret == 0)

0 commit comments

Comments
 (0)