include/cvw/qt/bridging.hpp
Conversion utilities between cv::Mat/QImage and Image<QImage>. More...
Namespaces
| Name |
|---|
| cvw |
Detailed Description
Conversion utilities between cv::Mat/QImage and Image<QImage>.
Author: Charliechen114514
Version: 1.0.0
Since: 1.0.0
Date: 2026-05-15
Provides bidirectional conversion between OpenCV and Qt image types, supporting both shared-memory and deep-copy modes. Also includes convenience wrappers for converting Image<F> directly to QImage.
Source code
cpp
#pragma once
#include <QImage>
#include <cstdint>
#include <cvw/base/expected.hpp>
#include <cvw/image.hpp>
#include <opencv2/core/mat.hpp>
namespace cvw {
enum class ConvertionalError : uint8_t {
InternalError,
UnsupportedFormat,
};
enum class ConvertionalMethod : uint8_t {
Copy,
Shared,
};
template <ConvertionalMethod Method> [[nodiscard("Dont throw away QImage")]]
inline cvw::expected<QImage, ConvertionalError> from_cv(const cv::Mat& mat) {
if (mat.empty()) {
return cvw::unexpected(ConvertionalError::InternalError);
}
QImage::Format fmt;
switch (mat.type()) {
case CV_8UC1:
fmt = QImage::Format_Grayscale8;
break;
case CV_8UC3:
fmt = QImage::Format_RGB888;
break;
case CV_8UC4:
fmt = QImage::Format_RGBA8888;
break;
default:
return cvw::unexpected(ConvertionalError::UnsupportedFormat);
}
QImage img(mat.data, mat.cols, mat.rows, static_cast<int>(mat.step), fmt);
if constexpr (Method == ConvertionalMethod::Copy) {
return img.copy();
} else {
return img;
}
}
template <ConvertionalMethod Method> [[nodiscard("Dont throw away cv Mat")]]
inline cvw::expected<cv::Mat, ConvertionalError> to_cv(const QImage& image) {
if (image.isNull()) {
return cvw::unexpected(ConvertionalError::InternalError);
}
int type;
switch (image.format()) {
case QImage::Format_Grayscale8:
type = CV_8UC1;
break;
case QImage::Format_RGB888:
type = CV_8UC3;
break;
case QImage::Format_RGBA8888:
case QImage::Format_ARGB32:
type = CV_8UC4;
break;
default:
return cvw::unexpected(ConvertionalError::UnsupportedFormat);
}
cv::Mat mat(image.height(), image.width(), type,
const_cast<uchar*>(image.constBits()),
static_cast<size_t>(image.bytesPerLine()));
if constexpr (Method == ConvertionalMethod::Copy) {
return mat.clone();
} else {
return mat;
}
}
} // namespace cvw
// ═══════════════════════════════════════════════════════════════
// Image<F> convenience wrappers
// ═══════════════════════════════════════════════════════════════
namespace cvw {
template <is_pixel_format F>
[[nodiscard]] inline cvw::expected<QImage, ConvertionalError>
to_qimage_view(const Image<F>& img) {
return from_cv<ConvertionalMethod::Shared>(img.mat());
}
template <is_pixel_format F>
[[nodiscard]] inline cvw::expected<QImage, ConvertionalError>
to_qimage_copy(const Image<F>& img) {
return from_cv<ConvertionalMethod::Copy>(img.mat());
}
} // namespace cvwUpdated on 2026-05-17 at 13:22:38 +0000