1 /* 2 Scan Tailor - Interactive post-processing tool for scanned pages. 3 Copyright (C) Joseph Artsimovich <joseph.artsimovich@gmail.com> 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #ifndef IMAGEPROC_GRAYIMAGE_H_ 20 #define IMAGEPROC_GRAYIMAGE_H_ 21 22 #include <QImage> 23 #include <QRect> 24 #include <QSize> 25 #include <cstdint> 26 27 namespace imageproc { 28 /** 29 * \brief A wrapper class around QImage that is always guaranteed to be 8-bit grayscale. 30 */ 31 class GrayImage { 32 public: 33 /** 34 * \brief Creates a 8-bit grayscale image with specified dimensions. 35 * 36 * The image contents won't be initialized. You can use fill() to initialize them. 37 * If size.isEmpty() is true, creates a null image. 38 * 39 * \throw std::bad_alloc Unlike the underlying QImage, GrayImage reacts to 40 * out-of-memory situations by throwing an exception rather than 41 * constructing a null image. 42 */ 43 explicit GrayImage(QSize size = QSize()); 44 45 /** 46 * \brief Constructs a 8-bit grayscale image by converting an arbitrary QImage. 47 * 48 * The QImage may be in any format and may be null. 49 */ 50 explicit GrayImage(const QImage& image); 51 52 /** 53 * \brief Returns a const reference to the underlying QImage. 54 * 55 * The underlying QImage is either a null image or a 8-bit indexed 56 * image with a grayscale palette. 57 */ toQImage()58 const QImage& toQImage() const { return m_image; } 59 60 operator const QImage&() const { return m_image; } 61 isNull()62 bool isNull() const { return m_image.isNull(); } 63 fill(uint8_t color)64 void fill(uint8_t color) { m_image.fill(color); } 65 data()66 uint8_t* data() { return m_image.bits(); } 67 data()68 const uint8_t* data() const { return m_image.bits(); } 69 70 /** 71 * \brief Number of bytes per line. 72 * 73 * This value may be larger than image width. 74 * An additional guaranee provided by the underlying QImage 75 * is that this value is a multiple of 4. 76 */ stride()77 int stride() const { return m_image.bytesPerLine(); } 78 size()79 QSize size() const { return m_image.size(); } 80 rect()81 QRect rect() const { return m_image.rect(); } 82 width()83 int width() const { return m_image.width(); } 84 height()85 int height() const { return m_image.height(); } 86 87 void invert(); 88 89 GrayImage inverted() const; 90 91 int dotsPerMeterX() const; 92 93 int dotsPerMeterY() const; 94 95 void setDotsPerMeterX(int value); 96 97 void setDotsPerMeterY(int value); 98 99 private: 100 QImage m_image; 101 }; 102 103 104 inline bool operator==(const GrayImage& lhs, const GrayImage& rhs) { 105 return lhs.toQImage() == rhs.toQImage(); 106 } 107 108 inline bool operator!=(const GrayImage& lhs, const GrayImage& rhs) { 109 return lhs.toQImage() != rhs.toQImage(); 110 } 111 } // namespace imageproc 112 #endif // ifndef IMAGEPROC_GRAYIMAGE_H_ 113