Overte C++ Documentation
Image.h
1 #pragma once
2 //
3 // Image.h
4 // image/src/Image
5 //
6 // Created by Olivier Prat on 29/3/2019.
7 // Copyright 2019 High Fidelity, Inc.
8 //
9 // Distributed under the Apache License, Version 2.0.
10 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
11 //
12 
13 #ifndef hifi_image_Image_h
14 #define hifi_image_Image_h
15 
16 #include <QImage>
17 
18 #include "ColorChannel.h"
19 
20 #include <glm/fwd.hpp>
21 #include <glm/vec2.hpp>
22 #include <GLMHelpers.h>
23 
24 namespace image {
25 
26  class Image {
27  public:
28 
29  enum Format {
30  Format_Invalid = QImage::Format_Invalid,
31  Format_Mono = QImage::Format_Mono,
32  Format_MonoLSB = QImage::Format_MonoLSB,
33  Format_Indexed8 = QImage::Format_Indexed8,
34  Format_RGB32 = QImage::Format_RGB32,
35  Format_ARGB32 = QImage::Format_ARGB32,
36  Format_ARGB32_Premultiplied = QImage::Format_ARGB32_Premultiplied,
37  Format_RGB16 = QImage::Format_RGB16,
38  Format_ARGB8565_Premultiplied = QImage::Format_ARGB8565_Premultiplied,
39  Format_RGB666 = QImage::Format_RGB666,
40  Format_ARGB6666_Premultiplied = QImage::Format_ARGB6666_Premultiplied,
41  Format_RGB555 = QImage::Format_RGB555,
42  Format_ARGB8555_Premultiplied = QImage::Format_ARGB8555_Premultiplied,
43  Format_RGB888 = QImage::Format_RGB888,
44  Format_RGB444 = QImage::Format_RGB444,
45  Format_ARGB4444_Premultiplied = QImage::Format_ARGB4444_Premultiplied,
46  Format_RGBX8888 = QImage::Format_RGBX8888,
47  Format_RGBA8888 = QImage::Format_RGBA8888,
48  Format_RGBA8888_Premultiplied = QImage::Format_RGBA8888_Premultiplied,
49  Format_Grayscale8 = QImage::Format_Grayscale8,
50  Format_R11G11B10F = QImage::Format_RGB30,
51  Format_PACKED_FLOAT = Format_R11G11B10F,
52  // RGBA 32 bit single precision float per component
53  Format_RGBAF = 100
54  };
55 
56  using AspectRatioMode = Qt::AspectRatioMode;
57  using TransformationMode = Qt::TransformationMode;
58 
59  Image() : _dims(0,0) {}
60  Image(int width, int height, Format format);
61  Image(const QImage& data) : _packedData(data), _dims(data.width(), data.height()), _format((Format)data.format()) {}
62  Image(const Image &other) = default;
63  void operator=(const QImage& other) {
64  _packedData = other;
65  _floatData.clear();
66  _dims.x = other.width();
67  _dims.y = other.height();
68  _format = (Format)other.format();
69  }
70 
71  void operator=(const Image& other) {
72  if (&other != this) {
73  _packedData = other._packedData;
74  _floatData = other._floatData;
75  _dims = other._dims;
76  _format = other._format;
77  }
78  }
79 
80  bool isNull() const { return _packedData.isNull() && _floatData.empty(); }
81 
82  Format getFormat() const { return _format; }
83  bool hasAlphaChannel() const { return _packedData.hasAlphaChannel() || _format == Format_RGBAF; }
84  bool hasFloatFormat() const { return _format == Format_R11G11B10F || _format == Format_RGBAF; }
85 
86  glm::uint32 getWidth() const { return (glm::uint32)_dims.x; }
87  glm::uint32 getHeight() const { return (glm::uint32)_dims.y; }
88  glm::uvec2 getSize() const { return glm::uvec2(_dims); }
89  size_t getByteCount() const;
90  size_t getBytesPerLineCount() const;
91 
92  QRgb getPackedPixel(int x, int y) const {
93  assert(_format != Format_RGBAF);
94  return _packedData.pixel(x, y);
95  }
96  void setPackedPixel(int x, int y, QRgb value) {
97  assert(_format != Format_RGBAF);
98  _packedData.setPixel(x, y, value);
99  }
100 
101  glm::vec4 getFloatPixel(int x, int y) const {
102  assert(_format == Format_RGBAF);
103  return _floatData[x + y*_dims.x];
104  }
105  void setFloatPixel(int x, int y, const glm::vec4& value) {
106  assert(_format == Format_RGBAF);
107  _floatData[x + y * _dims.x] = value;
108  }
109 
110  glm::uint8* editScanLine(int y);
111  const glm::uint8* getScanLine(int y) const;
112  glm::uint8* editBits();
113  const glm::uint8* getBits() const;
114 
115  Image getScaled(glm::uvec2 newSize, AspectRatioMode ratioMode, TransformationMode transformationMode = Qt::SmoothTransformation) const;
116  Image getConvertedToFormat(Format newFormat) const;
117  Image getSubImage(QRect rect) const;
118  Image getMirrored(bool horizontal, bool vertical) const;
119 
120  // Inplace transformations
121  void invertPixels();
122 
123  private:
124 
125  using FloatPixels = std::vector<glm::vec4>;
126 
127  // For QImage supported formats
128  QImage _packedData;
129  FloatPixels _floatData;
130  glm::ivec2 _dims;
131  Format _format { Format_Invalid };
132  };
133 
134 } // namespace image
135 
136 #endif // hifi_image_Image_h