diff --git a/doc/function/to_image.txt b/doc/function/to_image.txt
index 2947c05a0..829d30879 100644
--- a/doc/function/to_image.txt
+++ b/doc/function/to_image.txt
@@ -7,11 +7,13 @@ DOC_MSE_VERSION: since 0.3.8
Convert any value to a [[type:image]].
-A string is interpreted as a [[type:filename]].
+* A string is interpreted as a [[type:filename]].
+* A [[type:card]] will be converted into an image onto which image operations can be done.
--Parameters--
! Parameter Type Description
| @input@ ''any type'' Value to convert to an image
+| @zoom@ [[type:double]] (optional) A zoom value for the image. Only used when converting cards. This allows you to keep the sharpness of the text at higher resolution.
--Examples--
>>> to_image("image1.png") ==
diff --git a/src/data/format/formats.hpp b/src/data/format/formats.hpp
index 4e317ca01..e95683515 100644
--- a/src/data/format/formats.hpp
+++ b/src/data/format/formats.hpp
@@ -99,7 +99,7 @@ void export_images(const SetP& set, const vector& cards,
void export_image(const SetP& set, const CardP& card, const String& filename);
/// Generate a bitmap image of a card
-Bitmap export_bitmap(const SetP& set, const CardP& card);
+Bitmap export_bitmap(const SetP& set, const CardP& card, double zoom = 1.0);
/// Export a set to Magic Workstation format
void export_mws(Window* parent, const SetP& set);
diff --git a/src/data/format/image.cpp b/src/data/format/image.cpp
index 3b36ad786..b975884e9 100644
--- a/src/data/format/image.cpp
+++ b/src/data/format/image.cpp
@@ -24,10 +24,10 @@ void export_image(const SetP& set, const CardP& card, const String& filename) {
// but image.saveFile determines it automagicly
}
-class UnzoomedDataViewer : public DataViewer {
+class ZoomOverrideDataViewer : public DataViewer {
public:
- UnzoomedDataViewer(bool use_zoom_settings)
- : use_zoom_settings(use_zoom_settings)
+ ZoomOverrideDataViewer(bool use_zoom_settings, double zoom = 1.0)
+ : use_zoom_settings(use_zoom_settings), zoom(zoom)
{}
Rotation getRotation() const override;
private:
@@ -35,19 +35,23 @@ class UnzoomedDataViewer : public DataViewer {
double zoom = 1.0;
double angle = 0.0;
};
-Rotation UnzoomedDataViewer::getRotation() const {
+Rotation ZoomOverrideDataViewer::getRotation() const {
+ Rotation rot;
if (use_zoom_settings) {
- return DataViewer::getRotation();
- } else {
+ rot = DataViewer::getRotation();
+ rot.setZoom(rot.getZoom() * zoom);
+ }
+ else {
if (!stylesheet) stylesheet = set->stylesheet;
- return Rotation(angle, stylesheet->getCardRect(), zoom, 1.0, ROTATION_ATTACH_TOP_LEFT);
+ rot = Rotation(angle, stylesheet->getCardRect(), zoom, 1.0, ROTATION_ATTACH_TOP_LEFT);
}
+ return rot;
}
-Bitmap export_bitmap(const SetP& set, const CardP& card) {
+Bitmap export_bitmap(const SetP& set, const CardP& card, double zoom /*= 1.0*/) {
if (!set) throw Error(_("no set"));
// create viewer
- UnzoomedDataViewer viewer(!settings.stylesheetSettingsFor(set->stylesheetFor(card)).card_normal_export());
+ ZoomOverrideDataViewer viewer(!settings.stylesheetSettingsFor(set->stylesheetFor(card)).card_normal_export(), zoom);
viewer.setSet(set);
viewer.setCard(card);
// size of cards
diff --git a/src/gfx/generated_image.cpp b/src/gfx/generated_image.cpp
index 5465c16f0..91dba5140 100644
--- a/src/gfx/generated_image.cpp
+++ b/src/gfx/generated_image.cpp
@@ -504,3 +504,21 @@ bool ImageValueToImage::operator == (const GeneratedImage& that) const {
return that2 && filename == that2->filename
&& age == that2->age;
}
+
+// ----------------------------------------------------------------------------- : PreGeneratedImage
+
+PreGeneratedImage::PreGeneratedImage(const Image& image)
+ : image(image)
+{}
+PreGeneratedImage::~PreGeneratedImage() {}
+
+Image PreGeneratedImage::generate(const Options& opt) const {
+ if (!image.Ok()) {
+ return Image(max(1, opt.width), max(1, opt.height));
+ }
+ return image;
+}
+bool PreGeneratedImage::operator == (const GeneratedImage& that) const {
+ const PreGeneratedImage* that2 = dynamic_cast(&that);
+ return that2 && image.IsSameAs(that2->image);
+}
diff --git a/src/gfx/generated_image.hpp b/src/gfx/generated_image.hpp
index fd14ccd12..c2682d792 100644
--- a/src/gfx/generated_image.hpp
+++ b/src/gfx/generated_image.hpp
@@ -386,3 +386,17 @@ class ImageValueToImage : public GeneratedImage {
Age age; ///< Age the image was last updated
};
+// ----------------------------------------------------------------------------- : PreGeneratedImage
+
+/// Use an image from an ImageValue as an image
+class PreGeneratedImage : public GeneratedImage {
+public:
+ PreGeneratedImage(const Image& image);
+ ~PreGeneratedImage();
+ Image generate(const Options& opt) const override;
+ bool operator == (const GeneratedImage& that) const override;
+ bool local() const override { return true; }
+private:
+ PreGeneratedImage(const PreGeneratedImage&); // copy ctor
+ Image image;
+};
diff --git a/src/script/functions/image.cpp b/src/script/functions/image.cpp
index 3e9caf65d..26a2a2ff7 100644
--- a/src/script/functions/image.cpp
+++ b/src/script/functions/image.cpp
@@ -16,6 +16,8 @@
#include
#include
#include
+#include
+#include
#include
#include
@@ -24,8 +26,15 @@ void parse_enum(const String&, ImageCombine& out);
// ----------------------------------------------------------------------------- : Utility
SCRIPT_FUNCTION(to_image) {
- SCRIPT_PARAM_C(GeneratedImageP, input);
- return input;
+ SCRIPT_PARAM_C(ScriptValueP, input);
+ ScriptObject* card = dynamic_cast*>(input.get());
+ if (card) {
+ SCRIPT_OPTIONAL_PARAM_(double, zoom);
+ if (zoom <= 0) zoom = 1; // default
+ Image image = export_bitmap(export_info()->set, card->getValue(), zoom).ConvertToImage();
+ return make_intrusive(image);
+ }
+ return input->toImage();
}
// ----------------------------------------------------------------------------- : Image functions
diff --git a/src/script/value.cpp b/src/script/value.cpp
index 1927371ed..ed10eb507 100644
--- a/src/script/value.cpp
+++ b/src/script/value.cpp
@@ -37,7 +37,7 @@ wxDateTime ScriptValue::toDateTime() const {
throw ScriptErrorConversion(typeName(), _TYPE_("date"));
}
GeneratedImageP ScriptValue::toImage() const {
- throw ScriptErrorConversion(typeName(), _TYPE_("image" ));
+ throw ScriptErrorConversion(typeName(), _TYPE_("image"));
}
String ScriptValue::toCode() const {
return toString();