mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
ensure image script functions preserve metadata
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <util/prec.hpp>
|
||||
#include <data/format/image_encoding.hpp>
|
||||
#include <gfx/gfx.hpp>
|
||||
#include <util/error.hpp>
|
||||
|
||||
@@ -70,7 +71,10 @@ void linear_blend(Image& img1, const Image& img2, double x1,double y1, double x2
|
||||
alpha2 += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//transfer metadata
|
||||
img1.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata_merge(img1, img2));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Mask Blend
|
||||
@@ -101,7 +105,10 @@ void mask_blend(Image& img1, const Image& img2, const Image& mask) {
|
||||
// use mask's red channel to blend alpha (all mask channels should be identical since it's grey scale)
|
||||
alpha1[i] = (alpha1[i] * dataM[i * 3] + alpha2[i] * (255 - dataM[i * 3])) / 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//transfer metadata
|
||||
img1.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata_merge(img1, img2));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Alpha
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <util/prec.hpp>
|
||||
#include <data/format/image_encoding.hpp>
|
||||
#include <gfx/gfx.hpp>
|
||||
#include <util/reflect.hpp>
|
||||
#include <algorithm>
|
||||
@@ -575,7 +576,10 @@ void combine_image(Image& a, const Image& b, ImageCombine combine) {
|
||||
DISPATCH(COMBINE_SMALLER_THAN_240);
|
||||
DISPATCH(COMBINE_SMALLER_THAN_245);
|
||||
DISPATCH(COMBINE_SMALLER_THAN_250);
|
||||
}
|
||||
}
|
||||
|
||||
//transfer metadata
|
||||
a.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata_merge(a, b));
|
||||
}
|
||||
|
||||
void draw_combine_image(DC& dc, UInt x, UInt y, const Image& img, ImageCombine combine) {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <data/set.hpp>
|
||||
#include <data/symbol.hpp>
|
||||
#include <data/field/symbol.hpp>
|
||||
#include <script/functions/json.hpp>
|
||||
#include <render/symbol/filter.hpp>
|
||||
#include <gui/util.hpp> // load_resource_image
|
||||
#include <gui/web_request_window.hpp>
|
||||
@@ -297,6 +298,11 @@ Image EnlargeImage::generate(const Options& opt) {
|
||||
for (int y = 0 ; y < h ; ++y) {
|
||||
memcpy(data2 + dw + (y+dh)*w2, data1 + y*w, w); // copy a line
|
||||
}
|
||||
}
|
||||
// transfer metadata
|
||||
if (img.HasOption(wxIMAGE_OPTION_PNG_DESCRIPTION)) {
|
||||
String metadata = transformAllEncodedRects(img.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION), RealRect::translate, dw, dh);
|
||||
larger.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
|
||||
}
|
||||
// done
|
||||
return larger;
|
||||
@@ -436,8 +442,8 @@ Image BleedEdgedImage::generate(const Options& opt) {
|
||||
}
|
||||
// transfer metadata
|
||||
if (base_img.HasOption(wxIMAGE_OPTION_PNG_DESCRIPTION)) {
|
||||
String desc = transformAllEncodedRects(base_img.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION), 1.0, 0.0, dw, dh, width, height);
|
||||
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, desc);
|
||||
String metadata = transformAllEncodedRects(base_img.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION), RealRect::translate, dw, dh);
|
||||
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
|
||||
}
|
||||
// done
|
||||
return img;
|
||||
@@ -481,9 +487,12 @@ Image InsertedImage::generate(const Options& opt) {
|
||||
alpha += 1;
|
||||
}
|
||||
img.Paste(base_img, base_x, base_y, wxIMAGE_ALPHA_BLEND_COMPOSE);
|
||||
img.Paste(inserted_img, inserted_x, inserted_y, wxIMAGE_ALPHA_BLEND_COMPOSE);
|
||||
img.Paste(inserted_img, inserted_x, inserted_y, wxIMAGE_ALPHA_BLEND_COMPOSE);
|
||||
// transfer metadata
|
||||
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata_merge(base_img, inserted_img, base_x, base_y, inserted_x, inserted_y));
|
||||
return img;
|
||||
}
|
||||
|
||||
ImageCombine InsertedImage::combine() const {
|
||||
return base_image->combine();
|
||||
}
|
||||
@@ -519,7 +528,29 @@ Image CropImage::generate(const Options& opt) {
|
||||
alpha += 1;
|
||||
}
|
||||
Image base_img = image->generate(opt);
|
||||
img.Paste(base_img, -(int)offset_x, -(int)offset_y, wxIMAGE_ALPHA_BLEND_OVER);
|
||||
img.Paste(base_img, -(int)offset_x, -(int)offset_y, wxIMAGE_ALPHA_BLEND_COMPOSE);
|
||||
// transfer metadata
|
||||
if (base_img.HasOption(wxIMAGE_OPTION_PNG_DESCRIPTION)) {
|
||||
String metadata = transformAllEncodedRects(base_img.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION), RealRect::translate, -offset_x, -offset_y);
|
||||
// prune out of bounds cards
|
||||
boost::json::array cardsv = metadata_to_json(metadata);
|
||||
boost::json::array inbounds_cardsv;
|
||||
for (int i = 0; i < cardsv.size(); i++) {
|
||||
boost::json::object cardv = cardsv[i].as_object();
|
||||
if (cardv.contains("bounds")) {
|
||||
String bounds = String(cardv["bounds"].as_string().c_str());
|
||||
RealRect rect(0.0, 0.0, 0.0, 0.0);
|
||||
int degrees = 0;
|
||||
if (decodeRectFromString(bounds, rect, degrees)) {
|
||||
rect = rect.intersect(RealRect(0.0, 0.0, width, height));
|
||||
if (rect.width <= 0.0 || rect.height <= 0.0 ) continue;
|
||||
}
|
||||
}
|
||||
inbounds_cardsv.emplace_back(cardv);
|
||||
}
|
||||
metadata = "<mse-card-data>" + json_ugly_print(inbounds_cardsv) + "</mse-card-data>";
|
||||
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
|
||||
}
|
||||
return img;
|
||||
}
|
||||
bool CropImage::operator == (const GeneratedImage& that) const {
|
||||
@@ -730,6 +761,19 @@ bool ImageValueToImage::operator == (const GeneratedImage& that) const {
|
||||
&& age == that2->age;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : SetMetadataImage
|
||||
|
||||
Image SetMetadataImage::generate(const Options& opt) {
|
||||
Image img = image->generate(opt);
|
||||
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
|
||||
return img;
|
||||
}
|
||||
bool SetMetadataImage::operator == (const GeneratedImage& that) const {
|
||||
const SetMetadataImage* that2 = dynamic_cast<const SetMetadataImage*>(&that);
|
||||
return that2 && *image == *that2->image
|
||||
&& metadata == that2->metadata;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : ImportedImage
|
||||
|
||||
ImportedImage::ImportedImage(Set* set, const String& filepath)
|
||||
|
||||
@@ -467,6 +467,20 @@ private:
|
||||
Age age; ///< Age the image was last updated
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : SetMetadataImage
|
||||
|
||||
/// Change the alpha channel of an image
|
||||
class SetMetadataImage : public SimpleFilterImage {
|
||||
public:
|
||||
inline SetMetadataImage(const GeneratedImageP& image, const String& metadata)
|
||||
: SimpleFilterImage(image), metadata(metadata)
|
||||
{}
|
||||
Image generate(const Options& opt) override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
private:
|
||||
String metadata;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : ExternalImage
|
||||
|
||||
/// Load an image from outside the data folder
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <util/prec.hpp>
|
||||
#include <data/format/image_encoding.hpp>
|
||||
#include <gfx/gfx.hpp>
|
||||
#include <util/error.hpp>
|
||||
#if defined(__WXMSW__) && wxUSE_WXDIB
|
||||
@@ -403,6 +404,11 @@ Image make_stroke_image(Image& img, Color stroke_color, int stroke_radius, int b
|
||||
for (int i = 0 ; i < blur_radius ; ++i) {
|
||||
blur_image_alpha(s_img, 3);
|
||||
}
|
||||
// transfer metadata
|
||||
if (img.HasOption(wxIMAGE_OPTION_PNG_DESCRIPTION)) {
|
||||
String metadata = transformAllEncodedRects(img.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION), RealRect::translate, margin, margin);
|
||||
s_img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
|
||||
}
|
||||
return s_img;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <util/prec.hpp>
|
||||
#include <gfx/gfx.hpp>
|
||||
#include <data/format/image_encoding.hpp>
|
||||
#include <util/error.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- : Resample passes
|
||||
@@ -152,6 +153,13 @@ void resample_and_clip(const Image& img_in, Image& img_out, wxRect rect) {
|
||||
Image img_temp(img_out.GetWidth(), rect.height, false);
|
||||
resample_pass(img_in, img_temp, offset_in, 0, rect.width, 1, img_temp.GetWidth(), 1, rect .GetHeight(), img_in.GetWidth(), img_temp.GetWidth());
|
||||
resample_pass(img_temp, img_out, 0, 0, rect.height, img_temp.GetWidth(), img_out .GetHeight(), img_temp.GetWidth(), img_temp.GetWidth(), 1, 1);
|
||||
}
|
||||
// transfer metadata
|
||||
if (img_in.HasOption(wxIMAGE_OPTION_PNG_DESCRIPTION)) {
|
||||
double scale_x = (double)img_out.GetWidth() / img_in.GetWidth();
|
||||
double scale_y = (double)img_out.GetHeight() / img_in.GetHeight();
|
||||
String metadata = transformAllEncodedRects(img_in.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION), RealRect::scale, scale_x, scale_y);
|
||||
img_out.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,11 +42,8 @@ Image rotate_image_impl(const Image& img) {
|
||||
}
|
||||
// transfer metadata
|
||||
if (img.HasOption(wxIMAGE_OPTION_PNG_DESCRIPTION)) {
|
||||
if (!almost_equal(Rotater::angle(), rad180)) {
|
||||
swap(width, height);
|
||||
}
|
||||
String desc = transformAllEncodedRects(img.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION), 1.0, Rotater::angle(), 0, 0, width, height);
|
||||
ret.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, desc);
|
||||
String metadata = transformAllEncodedRects(img.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION), RealRect::rotate, width, height, lround(rad_to_deg(Rotater::angle())));
|
||||
ret.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
|
||||
}
|
||||
// ret is rotated image
|
||||
return ret;
|
||||
@@ -102,8 +99,10 @@ Image rotate_image(const Image& image, Radians angle) {
|
||||
if (is_rad180(a)) return rotate_image_impl<Rotate180deg>(image);
|
||||
if (is_rad270(a)) return rotate_image_impl<Rotate270deg>(image);
|
||||
else {
|
||||
if (!image.HasAlpha()) const_cast<Image&>(image).InitAlpha();
|
||||
return image.Rotate(angle, wxPoint(0,0));
|
||||
if (!image.HasAlpha()) const_cast<Image&>(image).InitAlpha();
|
||||
Image ret = image.Rotate(angle, wxPoint(0,0));
|
||||
ret.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, image.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +131,10 @@ Image flip_image_horizontal(Image const& img) {
|
||||
if (img.HasAlpha()) {
|
||||
out.InitAlpha();
|
||||
do_flip(img.GetAlpha(), out.GetAlpha(), 1, w, h);
|
||||
}
|
||||
if (img.HasOption(wxIMAGE_OPTION_PNG_DESCRIPTION)) {
|
||||
String metadata = transformAllEncodedRects(img.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION), RealRect::flip, w, h, 1);
|
||||
out.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -143,6 +146,10 @@ Image flip_image_vertical(Image const& img) {
|
||||
if (img.HasAlpha()) {
|
||||
out.InitAlpha();
|
||||
do_flip(img.GetAlpha(), out.GetAlpha(), 1 * w, h);
|
||||
}
|
||||
if (img.HasOption(wxIMAGE_OPTION_PNG_DESCRIPTION)) {
|
||||
String metadata = transformAllEncodedRects(img.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION), RealRect::flip, w, h, 0);
|
||||
out.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user