Browse Source

Add `Image.save_png_to_buffer` method

Backported from da0457fa29e1ea63f89b1e1d73e72c4dc80a9966.

This commit additionally exposes the method to scripting (4.0).
Andrii Doroshenko (Xrayez) 5 years ago
parent
commit
a3cad44f44
4 changed files with 24 additions and 0 deletions
  1. 11 0
      core/image.cpp
  2. 3 0
      core/image.h
  3. 9 0
      drivers/png/resource_saver_png.cpp
  4. 1 0
      drivers/png/resource_saver_png.h

+ 11 - 0
core/image.cpp

@@ -85,6 +85,8 @@ const char *Image::format_names[Image::FORMAT_MAX] = {
 SavePNGFunc Image::save_png_func = NULL;
 SaveEXRFunc Image::save_exr_func = NULL;
 
+SavePNGBufferFunc Image::save_png_buffer_func = NULL;
+
 void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel) {
 
 	uint32_t ofs = (p_y * width + p_x) * p_pixelsize;
@@ -1898,6 +1900,14 @@ Error Image::save_png(const String &p_path) const {
 	return save_png_func(p_path, Ref<Image>((Image *)this));
 }
 
+PoolVector<uint8_t> Image::save_png_to_buffer() const {
+	if (save_png_buffer_func == NULL) {
+		return PoolVector<uint8_t>();
+	}
+
+	return save_png_buffer_func(Ref<Image>((Image *)this));
+}
+
 Error Image::save_exr(const String &p_path, bool p_grayscale) const {
 
 	if (save_exr_func == NULL)
@@ -2728,6 +2738,7 @@ void Image::_bind_methods() {
 
 	ClassDB::bind_method(D_METHOD("load", "path"), &Image::load);
 	ClassDB::bind_method(D_METHOD("save_png", "path"), &Image::save_png);
+	ClassDB::bind_method(D_METHOD("save_png_to_buffer"), &Image::save_png_to_buffer);
 	ClassDB::bind_method(D_METHOD("save_exr", "path", "grayscale"), &Image::save_exr, DEFVAL(false));
 
 	ClassDB::bind_method(D_METHOD("detect_alpha"), &Image::detect_alpha);

+ 3 - 0
core/image.h

@@ -47,6 +47,7 @@
 class Image;
 
 typedef Error (*SavePNGFunc)(const String &p_path, const Ref<Image> &p_img);
+typedef PoolVector<uint8_t> (*SavePNGBufferFunc)(const Ref<Image> &p_img);
 typedef Ref<Image> (*ImageMemLoadFunc)(const uint8_t *p_png, int p_size);
 
 typedef Error (*SaveEXRFunc)(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
@@ -57,6 +58,7 @@ class Image : public Resource {
 public:
 	static SavePNGFunc save_png_func;
 	static SaveEXRFunc save_exr_func;
+	static SavePNGBufferFunc save_png_buffer_func;
 
 	enum {
 		MAX_WIDTH = 16384, // force a limit somehow
@@ -259,6 +261,7 @@ public:
 
 	Error load(const String &p_path);
 	Error save_png(const String &p_path) const;
+	PoolVector<uint8_t> save_png_to_buffer() const;
 	Error save_exr(const String &p_path, bool p_grayscale) const;
 
 	/**

+ 9 - 0
drivers/png/resource_saver_png.cpp

@@ -71,6 +71,14 @@ Error ResourceSaverPNG::save_image(const String &p_path, const Ref<Image> &p_img
 	return OK;
 }
 
+PoolVector<uint8_t> ResourceSaverPNG::save_image_to_buffer(const Ref<Image> &p_img) {
+
+	PoolVector<uint8_t> buffer;
+	Error err = PNGDriverCommon::image_to_png(p_img, buffer);
+	ERR_FAIL_COND_V_MSG(err, PoolVector<uint8_t>(), "Can't convert image to PNG.");
+	return buffer;
+}
+
 bool ResourceSaverPNG::recognize(const RES &p_resource) const {
 
 	return (p_resource.is_valid() && p_resource->is_class("ImageTexture"));
@@ -86,4 +94,5 @@ void ResourceSaverPNG::get_recognized_extensions(const RES &p_resource, List<Str
 ResourceSaverPNG::ResourceSaverPNG() {
 
 	Image::save_png_func = &save_image;
+	Image::save_png_buffer_func = &save_image_to_buffer;
 };

+ 1 - 0
drivers/png/resource_saver_png.h

@@ -37,6 +37,7 @@
 class ResourceSaverPNG : public ResourceFormatSaver {
 public:
 	static Error save_image(const String &p_path, const Ref<Image> &p_img);
+	static PoolVector<uint8_t> save_image_to_buffer(const Ref<Image> &p_img);
 
 	virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
 	virtual bool recognize(const RES &p_resource) const;