diff --git a/.gitignore b/.gitignore index 79df30ccf..36cdf8fd1 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ coverage .DS_Store /.idea/ /prebuilds -miniqt \ No newline at end of file +miniqt +cmake-build-debug diff --git a/CMakeLists.txt b/CMakeLists.txt index 1970b6480..64048fbe0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,7 @@ add_library(${CORE_WIDGETS_ADDON} SHARED "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QPicture/qpicture_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QPixmap/qpixmap_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QIcon/qicon_wrap.cpp" + "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QImage/qimage_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QFont/qfont_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QCursor/qcursor_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QKeySequence/qkeysequence_wrap.cpp" diff --git a/src/cpp/include/nodegui/QtGui/QImage/qimage_wrap.h b/src/cpp/include/nodegui/QtGui/QImage/qimage_wrap.h new file mode 100644 index 000000000..efae63cb8 --- /dev/null +++ b/src/cpp/include/nodegui/QtGui/QImage/qimage_wrap.h @@ -0,0 +1,78 @@ +#pragma once + +#include + +#include + +#include "Extras/Export/export.h" +#include "core/Component/component_macro.h" + +class DLL_EXPORT QImageWrap : public Napi::ObjectWrap { + COMPONENT_WRAPPED_METHODS_DECLARATION + + private: + std::unique_ptr instance; + + public: + static Napi::FunctionReference constructor; + static Napi::Object init(Napi::Env env, Napi::Object exports); + QImageWrap(const Napi::CallbackInfo& info); + ~QImageWrap(); + QImage* getInternalInstance(); + + Napi::Value allGray(const Napi::CallbackInfo& info); + Napi::Value bitPlaneCount(const Napi::CallbackInfo& info); + Napi::Value bytesPerLine(const Napi::CallbackInfo& info); + Napi::Value cacheKey(const Napi::CallbackInfo& info); + Napi::Value color(const Napi::CallbackInfo& info); + Napi::Value colorCount(const Napi::CallbackInfo& info); + void convertTo(const Napi::CallbackInfo& info); + Napi::Value convertToFormat(const Napi::CallbackInfo& info); + Napi::Value copy(const Napi::CallbackInfo& info); + Napi::Value createAlphaMask(const Napi::CallbackInfo& info); + Napi::Value createHeuristicMask(const Napi::CallbackInfo& info); + Napi::Value depth(const Napi::CallbackInfo& info); + Napi::Value devicePixelRatio(const Napi::CallbackInfo& info); + Napi::Value dotsPerMeterX(const Napi::CallbackInfo& info); + Napi::Value dotsPerMeterY(const Napi::CallbackInfo& info); + void fill(const Napi::CallbackInfo& info); + Napi::Value format(const Napi::CallbackInfo& info); + Napi::Value hasAlphaChannel(const Napi::CallbackInfo& info); + Napi::Value height(const Napi::CallbackInfo& info); + void invertPixels(const Napi::CallbackInfo& info); + Napi::Value isGrayscale(const Napi::CallbackInfo& info); + Napi::Value isNull(const Napi::CallbackInfo& info); + Napi::Value load(const Napi::CallbackInfo& info); + Napi::Value loadFromData(const Napi::CallbackInfo& info); + Napi::Value mirrored(const Napi::CallbackInfo& info); + Napi::Value offset(const Napi::CallbackInfo& info); + Napi::Value pixelColor(const Napi::CallbackInfo& info); + Napi::Value pixelIndex(const Napi::CallbackInfo& info); + Napi::Value rect(const Napi::CallbackInfo& info); + Napi::Value reinterpretAsFormat(const Napi::CallbackInfo& info); + Napi::Value save(const Napi::CallbackInfo& info); + Napi::Value scaled(const Napi::CallbackInfo& info); + Napi::Value scaledToHeight(const Napi::CallbackInfo& info); + Napi::Value scaledToWidth(const Napi::CallbackInfo& info); + void setAlphaChannel(const Napi::CallbackInfo& info); + void setColor(const Napi::CallbackInfo& info); + void setColorCount(const Napi::CallbackInfo& info); + void setDevicePixelRatio(const Napi::CallbackInfo& info); + void setDotsPerMeterX(const Napi::CallbackInfo& info); + void setDotsPerMeterY(const Napi::CallbackInfo& info); + void setOffset(const Napi::CallbackInfo& info); + void setPixel(const Napi::CallbackInfo& info); + void setPixelColor(const Napi::CallbackInfo& info); + void setText(const Napi::CallbackInfo& info); + Napi::Value size(const Napi::CallbackInfo& info); + Napi::Value sizeInBytes(const Napi::CallbackInfo& info); + void swap(const Napi::CallbackInfo& info); + Napi::Value text(const Napi::CallbackInfo& info); + Napi::Value textKeys(const Napi::CallbackInfo& info); + Napi::Value valid(const Napi::CallbackInfo& info); + Napi::Value width(const Napi::CallbackInfo& info); +}; + +namespace StaticQImageWrapMethods { +DLL_EXPORT Napi::Value fromQVariant(const Napi::CallbackInfo& info); +} // namespace StaticQImageWrapMethods diff --git a/src/cpp/include/nodegui/QtGui/QPixmap/qpixmap_wrap.h b/src/cpp/include/nodegui/QtGui/QPixmap/qpixmap_wrap.h index 446fc771a..4a7d36c24 100644 --- a/src/cpp/include/nodegui/QtGui/QPixmap/qpixmap_wrap.h +++ b/src/cpp/include/nodegui/QtGui/QPixmap/qpixmap_wrap.h @@ -26,6 +26,7 @@ class DLL_EXPORT QPixmapWrap : public Napi::ObjectWrap { Napi::Value scaled(const Napi::CallbackInfo& info); Napi::Value height(const Napi::CallbackInfo& info); Napi::Value width(const Napi::CallbackInfo& info); + static Napi::Value fromImage(const Napi::CallbackInfo& info); }; namespace StaticQPixmapWrapMethods { diff --git a/src/cpp/lib/QtGui/QImage/qimage_wrap.cpp b/src/cpp/lib/QtGui/QImage/qimage_wrap.cpp new file mode 100644 index 000000000..86a878bf8 --- /dev/null +++ b/src/cpp/lib/QtGui/QImage/qimage_wrap.cpp @@ -0,0 +1,697 @@ +#include "QtGui/QImage/qimage_wrap.h" + +#include "Extras/Utils/nutils.h" +#include "QtCore/QPoint/qpoint_wrap.h" +#include "QtCore/QVariant/qvariant_wrap.h" +#include "QtCore/QRect/qrect_wrap.h" +#include "QtCore/QSize/qsize_wrap.h" +#include "QtGui/QColor/qcolor_wrap.h" + +Napi::FunctionReference QImageWrap::constructor; + +Napi::Object QImageWrap::init(Napi::Env env, Napi::Object exports) { + Napi::HandleScope scope(env); + char CLASSNAME[] = "QImage"; + Napi::Function func = DefineClass( + env, CLASSNAME, + {InstanceMethod("allGray", &QImageWrap::allGray), + InstanceMethod("bitPlaneCount", &QImageWrap::bitPlaneCount), + InstanceMethod("bytesPerLine", &QImageWrap::bytesPerLine), + InstanceMethod("cacheKey", &QImageWrap::cacheKey), + InstanceMethod("color", &QImageWrap::color), + InstanceMethod("colorCount", &QImageWrap::colorCount), + InstanceMethod("convertTo", &QImageWrap::convertTo), + InstanceMethod("convertToFormat", &QImageWrap::convertToFormat), + InstanceMethod("copy", &QImageWrap::copy), + InstanceMethod("createAlphaMask", &QImageWrap::createAlphaMask), + InstanceMethod("createHeuristicMask", &QImageWrap::createHeuristicMask), + InstanceMethod("depth", &QImageWrap::depth), + InstanceMethod("devicePixelRatio", &QImageWrap::devicePixelRatio), + InstanceMethod("dotsPerMeterX", &QImageWrap::dotsPerMeterX), + InstanceMethod("dotsPerMeterY", &QImageWrap::dotsPerMeterY), + InstanceMethod("fill", &QImageWrap::fill), + InstanceMethod("format", &QImageWrap::format), + InstanceMethod("hasAlphaChannel", &QImageWrap::hasAlphaChannel), + InstanceMethod("height", &QImageWrap::height), + InstanceMethod("invertPixels", &QImageWrap::invertPixels), + InstanceMethod("isGrayscale", &QImageWrap::isGrayscale), + InstanceMethod("isNull", &QImageWrap::isNull), + InstanceMethod("load", &QImageWrap::load), + InstanceMethod("loadFromData", &QImageWrap::loadFromData), + InstanceMethod("mirrored", &QImageWrap::mirrored), + InstanceMethod("offset", &QImageWrap::offset), + InstanceMethod("pixelColor", &QImageWrap::pixelColor), + InstanceMethod("pixelIndex", &QImageWrap::pixelIndex), + InstanceMethod("rect", &QImageWrap::rect), + InstanceMethod("reinterpretAsFormat", &QImageWrap::reinterpretAsFormat), + InstanceMethod("save", &QImageWrap::save), + InstanceMethod("scaled", &QImageWrap::scaled), + InstanceMethod("scaledToHeight", &QImageWrap::scaledToHeight), + InstanceMethod("scaledToWidth", &QImageWrap::scaledToWidth), + InstanceMethod("setAlphaChannel", &QImageWrap::setAlphaChannel), + InstanceMethod("setColor", &QImageWrap::setColor), + InstanceMethod("setColorCount", &QImageWrap::setColorCount), + InstanceMethod("setDevicePixelRatio", &QImageWrap::setDevicePixelRatio), + InstanceMethod("setDotsPerMeterX", &QImageWrap::setDotsPerMeterX), + InstanceMethod("setDotsPerMeterY", &QImageWrap::setDotsPerMeterY), + InstanceMethod("setOffset", &QImageWrap::setOffset), + InstanceMethod("setPixel", &QImageWrap::setPixel), + InstanceMethod("setPixelColor", &QImageWrap::setPixelColor), + InstanceMethod("setText", &QImageWrap::setText), + InstanceMethod("size", &QImageWrap::size), + InstanceMethod("sizeInBytes", &QImageWrap::sizeInBytes), + InstanceMethod("swap", &QImageWrap::swap), + InstanceMethod("text", &QImageWrap::text), + InstanceMethod("textKeys", &QImageWrap::textKeys), + InstanceMethod("valid", &QImageWrap::valid), + InstanceMethod("width", &QImageWrap::width), + COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE(QImageWrap)}); + constructor = Napi::Persistent(func); + exports.Set(CLASSNAME, func); + return exports; +} + +QImageWrap::QImageWrap(const Napi::CallbackInfo& info) + : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + if (info.Length() == 0) { + this->instance = std::make_unique(); + } else if (info.Length() == 1 && info[0].IsString()) { + QString filename(info[0].As().Utf8Value().c_str()); + this->instance = std::make_unique(filename); + } else if (info.Length() == 1 && info[0].IsExternal()) { + this->instance = + std::unique_ptr(info[0].As>().Data()); + } else if (info.Length() == 3) { + int32_t width = info[0].As(); + int32_t height = info[1].As(); + QImage::Format format = + static_cast(info[2].As().Int32Value()); + this->instance = std::make_unique(width, height, format); + } else if (info.Length() == 2) { + QSizeWrap* size = + Napi::ObjectWrap::Unwrap(info[0].As()); + QImage::Format format = + static_cast(info[1].As().Int32Value()); + this->instance = + std::make_unique(*(size->getInternalInstance()), format); + } else { + Napi::TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + } +} + +QImageWrap::~QImageWrap() { this->instance.reset(); } +QImage* QImageWrap::getInternalInstance() { return this->instance.get(); } + +Napi::Value QImageWrap::allGray(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + return Napi::Boolean::New(env, instance->allGray()); +} + +Napi::Value QImageWrap::bitPlaneCount(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + return Napi::Number::New(env, instance->bitPlaneCount()); +} + +Napi::Value QImageWrap::bytesPerLine(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + return Napi::Number::New(env, instance->bytesPerLine()); +} + +Napi::Value QImageWrap::cacheKey(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + return Napi::Number::New(env, instance->cacheKey()); +} + +Napi::Value QImageWrap::color(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + int64_t i = info[0].As(); + return Napi::Number::New(env, instance->color(i)); +} + +Napi::Value QImageWrap::colorCount(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + return Napi::Number::New(env, instance->colorCount()); +} + +void QImageWrap::convertTo(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + QImage::Format format = + static_cast(info[0].As().Int32Value()); + Qt::ImageConversionFlag conversionFlags = + static_cast( + info[1].As().Int32Value()); + this->instance->convertTo(format, conversionFlags); +} + +Napi::Value QImageWrap::convertToFormat(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + QImage::Format format = + static_cast(info[0].As().Int32Value()); + Qt::ImageConversionFlag conversionFlags = + static_cast( + info[1].As().Int32Value()); + auto img = this->instance->convertToFormat(format, conversionFlags); + auto instance = QImageWrap::constructor.New( + {Napi::External::New(env, new QImage(img))}); + return instance; +} + +Napi::Value QImageWrap::copy(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + if (info.Length() == 1) { + QRect* rect = + Napi::ObjectWrap::Unwrap(info[0].As()) + ->getInternalInstance(); + QImage img = this->instance->copy(*rect); + auto instance = QImageWrap::constructor.New( + {Napi::External::New(env, new QImage(img))}); + return instance; + } + + int64_t x = info[0].As(); + int64_t y = info[1].As(); + int64_t width = info[2].As(); + int64_t height = info[3].As(); + QImage img = this->instance->copy(x, y, width, height); + auto instance = QImageWrap::constructor.New( + {Napi::External::New(env, new QImage(img))}); + return instance; +} + +Napi::Value QImageWrap::createAlphaMask(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + Qt::ImageConversionFlags flags = static_cast( + info[0].As().Int32Value()); + QImage img = this->instance->createAlphaMask(flags); + auto instance = QImageWrap::constructor.New( + {Napi::External::New(env, new QImage(img))}); + return instance; +} + +Napi::Value QImageWrap::createHeuristicMask(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + bool clipTight = info[0].As(); + QImage img = this->instance->createHeuristicMask(clipTight); + auto instance = QImageWrap::constructor.New( + {Napi::External::New(env, new QImage(img))}); + img.save(QString("test.png")); + return instance; +} + +Napi::Value QImageWrap::depth(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Number::New(env, instance->depth()); + ; +} + +Napi::Value QImageWrap::devicePixelRatio(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Number::New(env, instance->devicePixelRatio()); + ; +} + +Napi::Value QImageWrap::dotsPerMeterX(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Number::New(env, instance->dotsPerMeterX()); + ; +} + +Napi::Value QImageWrap::dotsPerMeterY(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Number::New(env, instance->dotsPerMeterY()); + ; +} + +void QImageWrap::fill(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + if (info[0].IsObject()) { + QColor* color = + Napi::ObjectWrap::Unwrap(info[0].As()) + ->getInternalInstance(); + this->instance->fill(*color); + return; + } + + int32_t color = info[0].As(); + this->instance->fill(static_cast(color)); +} + +Napi::Value QImageWrap::format(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Number::New(env, this->instance->format()); +} + +Napi::Value QImageWrap::hasAlphaChannel(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Boolean::New(env, this->instance->hasAlphaChannel()); +} + +Napi::Value QImageWrap::height(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Number::New(env, this->instance->height()); +} + +void QImageWrap::invertPixels(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QImage::InvertMode mode = + static_cast(info[0].As().Int32Value()); + this->instance->invertPixels(mode); +} + +Napi::Value QImageWrap::isGrayscale(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Boolean::New(env, this->instance->isGrayscale()); +} + +Napi::Value QImageWrap::isNull(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Boolean::New(env, this->instance->isNull()); +} + +Napi::Value QImageWrap::load(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QString fileName = QString(info[0].As().Utf8Value().c_str()); + if (info.Length() == 2 && !info[1].IsNull()) { + std::string format = info[1].As().Utf8Value(); + return Napi::Boolean::New(env, + this->instance->load(fileName, format.c_str())); + } + + return Napi::Boolean::New(env, this->instance->load(fileName)); +} + +Napi::Value QImageWrap::loadFromData(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + Napi::Buffer buffer = info[0].As>(); + if (info.Length() == 2 && !info[1].IsNull()) { + std::string format = info[1].As().Utf8Value(); + return Napi::Boolean::New( + env, this->instance->loadFromData(buffer.Data(), buffer.Length(), + format.c_str())); + } + + return Napi::Boolean::New( + env, this->instance->loadFromData(buffer.Data(), buffer.Length())); +} + +Napi::Value QImageWrap::mirrored(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + bool horizontal = info[0].As(); + bool vertical = info[1].As(); + + QImage img = this->instance->mirrored(horizontal, vertical); + auto instance = QImageWrap::constructor.New( + {Napi::External::New(env, new QImage(img))}); + return instance; +} + +Napi::Value QImageWrap::offset(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QPoint point = this->instance->offset(); + auto instance = QPointWrap::constructor.New( + {Napi::External::New(env, new QPoint(point))}); + return instance; +} + +Napi::Value QImageWrap::pixelColor(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + if (info.Length() == 1) { + QPoint* point = + Napi::ObjectWrap::Unwrap(info[0].As()) + ->getInternalInstance(); + + QColor color = this->instance->pixelColor(*point); + auto instance = QColorWrap::constructor.New( + {Napi::External::New(env, new QColor(color))}); + return instance; + } + + int64_t x = info[0].As(); + int64_t y = info[1].As(); + + QColor color = this->instance->pixelColor(x, y); + auto instance = QColorWrap::constructor.New( + {Napi::External::New(env, new QColor(color))}); + return instance; +} + +Napi::Value QImageWrap::pixelIndex(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + if (info.Length() == 1) { + QPoint* point = + Napi::ObjectWrap::Unwrap(info[0].As()) + ->getInternalInstance(); + + return Napi::Number::New(env, this->instance->pixelIndex(*point)); + } + + int64_t x = info[0].As(); + int64_t y = info[1].As(); + return Napi::Number::New(env, this->instance->pixelIndex(x, y)); +} + +Napi::Value QImageWrap::rect(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QRect rect = this->instance->rect(); + auto instance = QRectWrap::constructor.New( + {Napi::External::New(env, new QRect(rect))}); + return instance; +} + +Napi::Value QImageWrap::reinterpretAsFormat(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QImage::Format format = + static_cast(info[0].As().Int32Value()); + return Napi::Boolean::New(env, this->instance->reinterpretAsFormat(format)); +} + +Napi::Value QImageWrap::save(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QString fileName(info[0].As().Utf8Value().c_str()); + Napi::Value format = info[1]; + int32_t quality = info[2].As(); + + return Napi::Boolean::New( + env, this->instance->save( + fileName, + format.IsNull() ? nullptr + : format.As().Utf8Value().c_str(), + quality)); +} + +Napi::Value QImageWrap::scaled(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + if (info.Length() == 3) { + QSize* size = + Napi::ObjectWrap::Unwrap(info[0].As()) + ->getInternalInstance(); + Qt::AspectRatioMode aspectRatioMode = static_cast( + info[1].As().Int32Value()); + Qt::TransformationMode transformMode = static_cast( + info[2].As().Int32Value()); + QImage image = + this->instance->scaled(*size, aspectRatioMode, transformMode); + auto instance = QImageWrap::constructor.New( + {Napi::External::New(env, new QImage(image))}); + return instance; + } + + int64_t width = info[0].As(); + int64_t height = info[1].As(); + Qt::AspectRatioMode aspectRatioMode = + static_cast(info[2].As().Int32Value()); + Qt::TransformationMode transformMode = static_cast( + info[3].As().Int32Value()); + QImage image = + this->instance->scaled(width, height, aspectRatioMode, transformMode); + auto instance = QImageWrap::constructor.New( + {Napi::External::New(env, new QImage(image))}); + return instance; +} + +Napi::Value QImageWrap::scaledToHeight(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int64_t height = info[0].As(); + Qt::TransformationMode mode = static_cast( + info[1].As().Int32Value()); + QImage image = this->instance->scaledToHeight(height, mode); + auto instance = QImageWrap::constructor.New( + {Napi::External::New(env, new QImage(image))}); + return instance; +} + +Napi::Value QImageWrap::scaledToWidth(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int64_t width = info[0].As(); + Qt::TransformationMode mode = static_cast( + info[1].As().Int32Value()); + QImage image = this->instance->scaledToWidth(width, mode); + auto instance = QImageWrap::constructor.New( + {Napi::External::New(env, new QImage(image))}); + return instance; +} + +void QImageWrap::setAlphaChannel(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QImage* image = + Napi::ObjectWrap::Unwrap(info[0].As()) + ->getInternalInstance(); + this->instance->setAlphaChannel(*image); +} + +void QImageWrap::setColor(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int64_t index = info[0].As(); + int64_t colorValue = info[1].As(); + this->instance->setColor(index, colorValue); +} + +void QImageWrap::setColorCount(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int64_t colorCount = info[0].As(); + this->instance->setColorCount(colorCount); +} + +void QImageWrap::setDevicePixelRatio(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int64_t scaleFactor = info[0].As(); + this->instance->setDevicePixelRatio(scaleFactor); +} + +void QImageWrap::setDotsPerMeterX(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int64_t x = info[0].As(); + this->instance->setDotsPerMeterX(x); +} + +void QImageWrap::setDotsPerMeterY(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int64_t y = info[0].As(); + this->instance->setDotsPerMeterY(y); +} + +void QImageWrap::setOffset(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QPoint* offset = + Napi::ObjectWrap::Unwrap(info[0].As()) + ->getInternalInstance(); + this->instance->setOffset(*offset); +} + +void QImageWrap::setPixel(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + if (info.Length() == 2) { + QPoint* position = + Napi::ObjectWrap::Unwrap(info[0].As()) + ->getInternalInstance(); + int64_t index_or_rgb = info[1].As(); + this->instance->setPixel(*position, index_or_rgb); + return; + } + + int64_t x = info[0].As(); + int64_t y = info[1].As(); + int64_t index_or_rgb = info[2].As(); + this->instance->setPixel(x, y, index_or_rgb); +} + +void QImageWrap::setPixelColor(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + if (info.Length() == 2) { + QPoint* position = + Napi::ObjectWrap::Unwrap(info[0].As()) + ->getInternalInstance(); + QColor* color = + Napi::ObjectWrap::Unwrap(info[1].As()) + ->getInternalInstance(); + this->instance->setPixelColor(*position, *color); + return; + } + + int64_t x = info[0].As(); + int64_t y = info[1].As(); + QColor* color = + Napi::ObjectWrap::Unwrap(info[2].As()) + ->getInternalInstance(); + this->instance->setPixelColor(x, y, *color); +} + +void QImageWrap::setText(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QString key(info[0].As().Utf8Value().c_str()); + QString value(info[1].As().Utf8Value().c_str()); + this->instance->setText(key, value); +} + +Napi::Value QImageWrap::size(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QSize size = this->instance->size(); + auto instance = QSizeWrap::constructor.New( + {Napi::External::New(env, new QSize(size))}); + return instance; +} + +Napi::Value QImageWrap::sizeInBytes(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Number::New(env, this->instance->sizeInBytes()); +} + +void QImageWrap::swap(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QImage* image = + Napi::ObjectWrap::Unwrap(info[0].As()) + ->getInternalInstance(); + this->instance->swap(*image); +} + +Napi::Value QImageWrap::text(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QString key = + this->instance->text(info[0].As().Utf8Value().c_str()); + return Napi::String::New(env, key.toUtf8().constData()); +} + +Napi::Value QImageWrap::textKeys(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QStringList keys = this->instance->textKeys(); + Napi::Array js_array = Napi::Array::New(env, keys.size()); + + for (int i = 0; i < keys.size(); i++) { + Napi::Value value = Napi::String::New(env, keys.at(i).toUtf8().constData()); + js_array[i] = value; + } + + return js_array; +} + +Napi::Value QImageWrap::valid(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + if (info.Length() == 1) { + QPoint* point = + Napi::ObjectWrap::Unwrap(info[0].As()) + ->getInternalInstance(); + return Napi::Boolean::New(env, this->instance->valid(*point)); + } + + int64_t x = info[0].As(); + int64_t y = info[1].As(); + + return Napi::Boolean::New(env, this->instance->valid(x, y)); +} + +Napi::Value QImageWrap::width(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Number::New(env, this->instance->width()); +} + + +Napi::Value StaticQImageWrapMethods::fromQVariant( + const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + Napi::Object variantObject = info[0].As(); + QVariantWrap* variantWrap = + Napi::ObjectWrap::Unwrap(variantObject); + QVariant* variant = variantWrap->getInternalInstance(); + QImage image = variant->value(); + auto instance = QImageWrap::constructor.New( + {Napi::External::New(env, new QImage(image))}); + return instance; +} diff --git a/src/cpp/lib/QtGui/QPixmap/qpixmap_wrap.cpp b/src/cpp/lib/QtGui/QPixmap/qpixmap_wrap.cpp index 37798ef52..89b0a780d 100644 --- a/src/cpp/lib/QtGui/QPixmap/qpixmap_wrap.cpp +++ b/src/cpp/lib/QtGui/QPixmap/qpixmap_wrap.cpp @@ -2,6 +2,7 @@ #include "Extras/Utils/nutils.h" #include "QtCore/QVariant/qvariant_wrap.h" +#include "QtGui/QImage/qimage_wrap.h" Napi::FunctionReference QPixmapWrap::constructor; @@ -16,6 +17,7 @@ Napi::Object QPixmapWrap::init(Napi::Env env, Napi::Object exports) { InstanceMethod("scaled", &QPixmapWrap::scaled), InstanceMethod("height", &QPixmapWrap::height), InstanceMethod("width", &QPixmapWrap::width), + StaticMethod("fromImage", &QPixmapWrap::fromImage), StaticMethod("fromQVariant", &StaticQPixmapWrapMethods::fromQVariant), COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE(QPixmapWrap)}); constructor = Napi::Persistent(func); @@ -143,6 +145,20 @@ Napi::Value QPixmapWrap::width(const Napi::CallbackInfo& info) { return Napi::Value::From(env, this->instance->width()); } +Napi::Value QPixmapWrap::fromImage(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + QImage* img = Napi::ObjectWrap::Unwrap(info[0].As()) + ->getInternalInstance(); + Qt::ImageConversionFlags flags = static_cast( + info[1].As().Int32Value()); + QPixmap pixmap = QPixmap::fromImage(*img, flags); + auto instance = QPixmapWrap::constructor.New( + {Napi::External::New(env, new QPixmap(pixmap))}); + return instance; +} + Napi::Value StaticQPixmapWrapMethods::fromQVariant( const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); diff --git a/src/cpp/main.cpp b/src/cpp/main.cpp index 359e93451..5e93903b9 100644 --- a/src/cpp/main.cpp +++ b/src/cpp/main.cpp @@ -32,6 +32,7 @@ #include "QtGui/QFont/qfont_wrap.h" #include "QtGui/QFontDatabase/qfontdatabase_wrap.h" #include "QtGui/QIcon/qicon_wrap.h" +#include "QtGui/QImage/qimage_wrap.h" #include "QtGui/QKeySequence/qkeysequence_wrap.h" #include "QtGui/QMovie/qmovie_wrap.h" #include "QtGui/QPen/qpen_wrap.h" @@ -137,6 +138,7 @@ Napi::Object Main(Napi::Env env, Napi::Object exports) { QKeySequenceWrap::init(env, exports); QFontDatabaseWrap::init(env, exports); QIconWrap::init(env, exports); + QImageWrap::init(env, exports); QFontWrap::init(env, exports); QMovieWrap::init(env, exports); QStyleWrap::init(env, exports); diff --git a/src/index.ts b/src/index.ts index 5b65613c7..9add0b634 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,6 +10,7 @@ export { QKeySequence } from './lib/QtGui/QKeySequence'; export { QPicture } from './lib/QtGui/QPicture'; export { QPixmap, ImageFormats } from './lib/QtGui/QPixmap'; export { QIcon, QIconMode, QIconState } from './lib/QtGui/QIcon'; +export { QImage } from './lib/QtGui/QImage'; export { QFont, QFontCapitalization, QFontStretch, QFontWeight } from './lib/QtGui/QFont'; export { QMovie, CacheMode, MovieState } from './lib/QtGui/QMovie'; export { QCursor } from './lib/QtGui/QCursor'; diff --git a/src/lib/QtGui/QImage.ts b/src/lib/QtGui/QImage.ts new file mode 100644 index 000000000..40f33443e --- /dev/null +++ b/src/lib/QtGui/QImage.ts @@ -0,0 +1,491 @@ +import { Component, NativeElement } from '../core/Component'; +import { checkIfNativeElement } from '../utils/helpers'; +import addon from '../utils/addon'; +import { ImageConversionFlag, GlobalColor, AspectRatioMode, TransformationMode } from '../QtEnums'; +import { QSize } from '../QtCore/QSize'; +import { QRect } from '../QtCore/QRect'; +import { QPoint } from '../QtCore/QPoint'; +import { QVariant } from '../QtCore/QVariant'; +import { QColor } from '../QtGui/QColor'; + +/** + +> The QImage class provides a hardware-independent image representation that + allows direct access to the pixel data, and can be used as a paint device. + +* **This class is a JS wrapper around Qt's [QImage class](https://doc.qt.io/qt-5/qimage.html)** + +### Example + +```javascript +const { QImage } = require('@nodegui/nodegui'); + +const image = new QImage(); +``` + */ +export class QImage extends Component { + native!: NativeElement; + + /** Constructs a null image */ + constructor(); + + constructor(native: NativeElement); + + /** Constructs an image and tries to load the image from the file with the given fileName */ + constructor(filename: string); + + /** Constructs an image with the given width, height and format */ + constructor(width: number, height: number, format: QImageFormat); + + /** Constructs an image with the given size and format */ + constructor(size: QSize, format: QImageFormat); + constructor( + arg?: QImage | NativeElement | QSize | string | number, + formatOrHeight?: QImageFormat | string | number, + format?: QImageFormat, + ) { + super(); + + if (checkIfNativeElement(arg)) { + this.native = arg as NativeElement; + } else if (typeof arg === 'string') { + this.native = new addon.QImage(arg); + } else if (typeof arg === 'number') { + this.native = new addon.QImage(arg, formatOrHeight, format); + } else if (arg instanceof QSize) { + this.native = new addon.QImage(arg.native, formatOrHeight); + } else { + this.native = new addon.QImage(); + } + } + + /** + * Returns true if all the colors in the image are shades of gray (i.e. their + * red, green and blue components are equal); otherwise false + */ + allGray(): boolean { + return this.native.allGray(); + } + + /** Returns the number of bit planes in the image */ + bitPlaneCount(): number { + return this.native.bitPlaneCount(); + } + + /** Returns the number of bytes per image scanline */ + bytesPerLine(): number { + return this.native.bytesPerLine(); + } + + /** + * Returns a number that identifies the contents of this QImage object. Distinct + * QImage objects can only have the same key if they refer to the same contents + */ + cacheKey(): number { + return this.native.cacheKey(); + } + + /** + * Returns the color in the color table at index i. The first color is at index 0 + */ + color(i: number): number { + return this.native.color(i); + } + + /** Returns the size of the color table for the image */ + colorCount(): number { + return this.native.colorCount(); + } + + /** Detach and convert the image to the given format in place */ + convertTo(format: QImageFormat, flags: ImageConversionFlag = ImageConversionFlag.AutoColor): void { + this.native.convertTo(format, flags); + } + + /** Returns a copy of the image in the given format */ + convertToFormat(format: QImageFormat, flags: ImageConversionFlag = ImageConversionFlag.AutoColor): QImage { + return new QImage(this.native.convertToFormat(format, flags)); + } + + /** Returns a sub-area of the image as a new image */ + copy(rectangle: QRect): QImage; + /** This is an overloaded function */ + copy(x: number, y: number, width: number, height: number): QImage; + copy(rectangleOrX: QRect | number, y?: number, width?: number, height?: number): QImage { + if (rectangleOrX instanceof QRect) { + return new QImage(this.native.copy(rectangleOrX.native)); + } + + return new QImage(this.native.copy(rectangleOrX, y, width, height)); + } + + /** + * Builds and returns a 1-bpp mask from the alpha buffer in this image. Returns + * a null image if the image's format is QImageFormat::Format_RGB32 + */ + createAlphaMask(flags: ImageConversionFlag = ImageConversionFlag.AutoColor): QImage { + return new QImage(this.native.createAlphaMask(flags)); + } + + /** Creates and returns a 1-bpp heuristic mask for this image */ + createHeuristicMask(clipTight = true): QImage { + return new QImage(this.native.createHeuristicMask(clipTight)); + } + + /** Returns the depth of the image */ + depth(): number { + return this.native.depth(); + } + + /** + * Returns the device pixel ratio for the image. This is the ratio + * between device pixels and device independent pixels. + */ + devicePixelRatio(): number { + return this.native.devicePixelRatio(); + } + + /** + * Returns the number of pixels that fit horizontally in a physical meter. Together + * with dotsPerMeterY(), this number defines the intended scale and aspect ratio of + * the image + */ + dotsPerMeterX(): number { + return this.native.dotsPerMeterX(); + } + + /** + * Returns the number of pixels that fit vertically in a physical meter. Together with + * dotsPerMeterX(), this number defines the intended scale and aspect ratio of the image + */ + dotsPerMeterY(): number { + return this.native.dotsPerMeterY(); + } + + /** Fills the entire image with the given color */ + fill(color: QColor | GlobalColor): void { + this.native.fill(color instanceof QColor ? color.native : color); + } + + /** Returns the format of the image */ + format(): QImageFormat { + return this.native.format(); + } + + /** + * Returns true if the image has a format that respects the alpha channel, otherwise + * returns false + */ + hasAlphaChannel(): boolean { + return this.native.hasAlphaChannel(); + } + + /** Returns the height of the image */ + height(): number { + return this.native.height(); + } + + /** Inverts all pixel values in the image */ + // eslint-disable-next-line + invertPixels(mode: QImageInvertMode = QImageInvertMode.InvertRgb): void { + this.native.invertPixels(mode); + } + + /** For 32-bit images, this function is equivalent to allGray() */ + isGrayscale(): boolean { + return this.native.isGrayscale(); + } + + /** Returns true if it is a null image, otherwise returns false */ + isNull(): boolean { + return this.native.isNull(); + } + + /** + * Loads an image from the file with the given fileName. Returns true if the image was + * successfully loaded; otherwise invalidates the image and returns false + */ + load(fileName: string, format: string | null = null): boolean { + return this.native.load(fileName, format); + } + + /** Loads an image from the specified buffer */ + loadFromData(data: Buffer, format: string | null = null): boolean { + return this.native.loadFromData(data, format); + } + + /** + * Returns a mirror of the image, mirrored in the horizontal and/or the vertical direction + * depending on whether horizontal and vertical are set to true or false + */ + mirrored(horizontal = false, vertical = true): QImage { + const native = this.native.mirrored(horizontal, vertical); + return new QImage(native); + } + + /** + * Returns the number of pixels by which the image is intended to be offset by when + * positioning relative to other images + */ + offset(): QPoint { + const native = this.native.offset(); + return new QPoint(native); + } + + /** Returns the color of the pixel at the given position as a QColor */ + pixelColor(point: QPoint): QColor; + /** Returns the color of the pixel at coordinates (x, y) as a QColor */ + pixelColor(x: number, y: number): QColor; + pixelColor(pointOrX: QPoint | number, y?: number): QColor { + const native = + pointOrX instanceof QPoint ? this.native.pixelColor(pointOrX.native) : this.native.pixelColor(pointOrX, y); + return new QColor(native); + } + + /** Returns the pixel index at the given position */ + pixelIndex(point: QPoint): number; + /** Returns the pixel index at (x, y) */ + pixelIndex(x: number, y: number): number; + pixelIndex(pointOrX: QPoint | number, y?: number): number { + const pixelIndex = + pointOrX instanceof QPoint ? this.native.pixelIndex(pointOrX.native) : this.native.pixelIndex(pointOrX, y); + return pixelIndex; + } + + /** Returns the enclosing rectangle (0, 0, width(), height()) of the image */ + rect(): QRect { + const native = this.native.rect(); + return new QRect(native); + } + + /** + * Changes the format of the image to format without changing the data. Only works + * between formats of the same depth. Returns true if successful + */ + reinterpretAsFormat(format: QImageFormat): boolean { + return this.native.reinterpretAsFormat(format); + } + + /** + * Saves the image to the file with the given fileName, using the given image file + * format and quality factor. If format is null, QImage will attempt to guess the + * format by looking at fileName's suffix. + */ + save(fileName: string, format: string | null = null, quality = -1): boolean { + return this.native.save(fileName, format, quality); + } + + /** + * Returns a copy of the image scaled to a rectangle defined by the given size according + * to the given aspectRatioMode and transformMode. + */ + scaled(size: QSize, aspectRatioMode: AspectRatioMode, transformMode: TransformationMode): QImage; + /** + * Returns a copy of the image scaled to a rectangle with the given width and height + * according to the given aspectRatioMode and transformMode. + */ + scaled(width: number, height: number, aspectRatioMode: AspectRatioMode, transformMode: TransformationMode): QImage; + scaled( + sizeOrWidth: QSize | number, + modeOrHeight: any, + transformOrAspectRatioMode: any, + transformMode?: any, + ): QImage { + let native; + if (sizeOrWidth instanceof QSize) { + native = this.native.scaled(sizeOrWidth.native, modeOrHeight, transformOrAspectRatioMode); + } else { + native = this.native.scaled(sizeOrWidth, modeOrHeight, transformOrAspectRatioMode, transformMode); + } + return new QImage(native); + } + + /** + * Returns a scaled copy of the image. The returned image is scaled to the given height + * using the specified transformation mode + */ + scaledToHeight(height: number, mode: TransformationMode = TransformationMode.FastTransformation): QImage { + const native = this.native.scaledToHeight(height, mode); + return new QImage(native); + } + + /** + * Returns a scaled copy of the image. The returned image is scaled to the given width + * using the specified transformation mode + */ + scaledToWidth(width: number, mode: TransformationMode = TransformationMode.FastTransformation): QImage { + const native = this.native.scaledToWidth(width, mode); + return new QImage(native); + } + + /** + * Sets the alpha channel of this image to the given alphaChannel + */ + setAlphaChannel(alphaChannel: QImage): void { + this.native.setAlphaChannel(alphaChannel.native); + } + + /** + * Sets the color at the given index in the color table, to the given to colorValue. + * The color value is an ARGB quadruplet + */ + setColor(index: number, colorValue: number): void { + this.native.setColor(index, colorValue); + } + + /** + * Resizes the color table to contain colorCount entries + */ + setColorCount(colorCount: number): void { + this.native.setColorCount(colorCount); + } + + /** + * Sets the device pixel ratio for the image. This is the ratio between image pixels + * and device-independent pixels + */ + setDevicePixelRatio(scaleFactory: number): void { + this.native.setDevicePixelRatio(scaleFactory); + } + + /** + * Sets the number of pixels that fit horizontally in a physical meter, to x + */ + setDotsPerMeterX(x: number): void { + this.native.setDotsPerMeterX(x); + } + + /** + * Sets the number of pixels that fit vertically in a physical meter, to y + */ + setDotsPerMeterY(y: number): void { + this.native.setDotsPerMeterY(y); + } + + /** + * Sets the number of pixels by which the image is intended to be offset by + * when positioning relative to other images, to offset + */ + setOffset(offset: QPoint): void { + this.native.setOffset(offset.native); + } + + /** Sets the pixel index or color at the given position to indexOrRgb */ + setPixel(position: QPoint, indexOrRgb: number): void; + /** Sets the pixel index or color at (x, y) to indexOrRgb */ + setPixel(x: number, y: number, indexOrRgb: number): void; + setPixel(positionOrX: QPoint | number, indexOrRgbOrY: number, indexOrRgb?: number): void { + if (positionOrX instanceof QPoint) { + this.native.setPixel(positionOrX.native, indexOrRgbOrY); + return; + } + this.native.setPixel(positionOrX, indexOrRgbOrY, indexOrRgb); + } + + /** Sets the color at the given position to color */ + setPixelColor(position: QPoint, color: QColor): void; + /** Sets the pixel color at (x, y) to color */ + setPixelColor(x: number, y: number, color: QColor): void; + setPixelColor(positionOrX: QPoint | number, colorOrY: QColor | number, color?: QColor): void { + if (positionOrX instanceof QPoint) { + this.native.setPixel(positionOrX.native, colorOrY); + return; + } + this.native.setPixel(positionOrX, colorOrY, color!.native); + } + + /** Sets the image text to the given text and associate it with the given key */ + setText(key: string, value: string): void { + this.native.setText(key, value); + } + + /** Returns the size of the image, i.e. its width() and height() */ + size(): QSize { + const native = this.native.size(); + return new QSize(native); + } + + /** Returns the image data size in bytes */ + sizeInBytes(): number { + return this.native.sizeInBytes(); + } + + /** Swaps image other with this image. This operation is very fast and never fails */ + swap(other: QImage): void { + this.native.swap(other.native); + } + + /** + * Returns the image text associated with the given key. If the specified key is an empty + * string, the whole image text is returned, with each key-text pair separated by a newline + */ + text(key: string): string { + return this.native.text(key); + } + + /** Returns the text keys for this image */ + textKeys(): string[] { + return this.native.textKeys(); + } + + /** Returns true if pos is a valid coordinate pair within the image; otherwise returns false */ + valid(pos: QPoint): boolean; + /** + * Returns true if QPoint(x, y) is a valid coordinate pair within the image; otherwise returns + * false + */ + valid(x: number, y: number): boolean; + valid(posOrX: QPoint | number, y?: number): boolean { + if (posOrX instanceof QPoint) { + return this.native.valid(posOrX.native); + } + return this.native.valid(posOrX, y); + } + + /** Returns the width of the image */ + width(): number { + return this.native.width(); + } + + static fromQVariant(variant: QVariant): QImage { + return new QImage(addon.QImage.fromQVariant(variant.native)); + } +} + +export enum QImageFormat { + Invalid, + Mono, + MonoLSB, + Indexed8, + RGB32, + ARGB32, + ARGB32_Premultiplied, + RGB16, + ARGB8565_Premultiplied, + RGB666, + ARGB6666_Premultiplied, + RGB555, + ARGB8555_Premultiplied, + RGB888, + RGB444, + ARGB4444_Premultiplied, + RGBX8888, + RGBA8888, + RGBA8888_Premultiplied, + BGR30, + A2BGR30_Premultiplied, + RGB30, + A2RGB30_Premultiplied, + Alpha8, + Grayscale8, + Grayscale16, + RGBX64, + RGBA64, + RGBA64_Premultiplied, + BGR888, +} + +export enum QImageInvertMode { + InvertRgb, + InvertRgba, +} diff --git a/src/lib/QtGui/QPixmap.ts b/src/lib/QtGui/QPixmap.ts index 21c08a1c0..3cabe183e 100644 --- a/src/lib/QtGui/QPixmap.ts +++ b/src/lib/QtGui/QPixmap.ts @@ -1,8 +1,9 @@ import addon from '../utils/addon'; import { Component, NativeElement } from '../core/Component'; -import { AspectRatioMode, TransformationMode } from '../QtEnums'; +import { AspectRatioMode, ImageConversionFlag, TransformationMode } from '../QtEnums'; import { checkIfNativeElement } from '../utils/helpers'; import { QVariant } from '../QtCore/QVariant'; +import { QImage } from './QImage'; /** @@ -68,6 +69,10 @@ export class QPixmap extends Component { width(): number { return this.native.width(); } + static fromImage(image: QImage, flags: ImageConversionFlag): QPixmap { + const native = addon.QPixmap.fromImage(image.native, flags); + return new QPixmap(native); + } static fromQVariant(variant: QVariant): QPixmap { return new QPixmap(addon.QPixmap.fromQVariant(variant.native)); }