Pencil2D Animation
Download Community News Docs Contribute
  • Overview
  • Articles
  • Code
  •  
  • Class List
  • Class Index
  • Class Hierarchy
  • Class Members
  • File List
Loading...
Searching...
No Matches
  • core_lib
  • src
  • graphics
  • bitmap
bitmapimage.h
1/*
2
3Pencil2D - Traditional Animation Software
4Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5Copyright (C) 2012-2020 Matthew Chiawen Chang
6
7This program is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; version 2 of the License.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16*/
17#ifndef BITMAP_IMAGE_H
18#define BITMAP_IMAGE_H
19
20#include <QPainter>
21#include "keyframe.h"
22#include <QtMath>
23#include <QHash>
24
25class TiledBuffer;
26
27class BitmapImage : public KeyFrame
28{
29public:
30 const QRgb transp = qRgba(0, 0, 0, 0);
31 const QRgb blackline = qRgba(1, 1, 1, 255);
32 const QRgb redline = qRgba(254,0,0,255);
33 const QRgb greenline = qRgba(0,254,0,255);
34 const QRgb blueline = qRgba(0,0,254,255);
35
36 BitmapImage();
37 BitmapImage(const BitmapImage&);
38 BitmapImage(const QRect &rectangle, const QColor& color);
39 BitmapImage(const QPoint& topLeft, const QImage& image);
40 BitmapImage(const QPoint& topLeft, const QString& path);
41
42 ~BitmapImage() override;
43 BitmapImage& operator=(const BitmapImage& a);
44
45 BitmapImage* clone() const override;
46
48 void loadFile() override;
49
51 void unloadFile() override;
52
58 bool isLoaded() const override;
59 quint64 memoryUsage() override;
60
61 void paintImage(QPainter& painter);
62 void paintImage(QPainter &painter, QImage &image, QRect sourceRect, QRect destRect);
63
64 QImage* image();
65 void setImage(QImage* pImg);
66
67 BitmapImage copy();
68 BitmapImage copy(QRect rectangle);
69 void paste(BitmapImage*, QPainter::CompositionMode cm = QPainter::CompositionMode_SourceOver);
70 void paste(const TiledBuffer* tiledBuffer, QPainter::CompositionMode cm = QPainter::CompositionMode_SourceOver);
71
72 void moveTopLeft(QPoint point);
73 void moveTopLeft(QPointF point) { moveTopLeft(point.toPoint()); }
74 void transform(QRect rectangle, bool smoothTransform);
75 void transform(QRectF rectangle, bool smoothTransform) { transform(rectangle.toRect(), smoothTransform); }
76 BitmapImage transformed(QRect selection, QTransform transform, bool smoothTransform);
77 BitmapImage transformed(QRect rectangle, bool smoothTransform);
78 BitmapImage transformed(QRectF rectangle, bool smoothTransform) { return transformed(rectangle.toRect(), smoothTransform); }
79
80 bool contains(QPoint P) { return mBounds.contains(P); }
81 bool contains(QPointF P) { return contains(P.toPoint()); }
82 void autoCrop();
83
84 QRgb pixel(int x, int y);
85 QRgb pixel(QPoint p);
86 void setPixel(int x, int y, QRgb color);
87 void setPixel(QPoint p, QRgb color);
88 void fillNonAlphaPixels(const QRgb color);
89
90 QRgb constScanLine(int x, int y) const;
91 void scanLine(int x, int y, QRgb color);
92 void clear();
93 void clear(QRect rectangle);
94 void clear(QRectF rectangle) { clear(rectangle.toRect()); }
95
96 static bool floodFill(BitmapImage** replaceImage, const BitmapImage* targetImage, const QRect& cameraRect, const QPoint& point, const QRgb& fillColor, int tolerance, const int expandValue);
97 static bool* floodFillPoints(const BitmapImage* targetImage,
98 const QRect& searchBounds,
99 QPoint point,
100 const int tolerance,
101 QRect& newBounds);
102 static void expandFill(bool* fillPixels, const QRect& searchBounds, const QRect& maxBounds, int expand);
103
104 void drawLine(QPointF P1, QPointF P2, QPen pen, QPainter::CompositionMode cm, bool antialiasing);
105 void drawRect(QRectF rectangle, QPen pen, QBrush brush, QPainter::CompositionMode cm, bool antialiasing);
106 void drawEllipse(QRectF rectangle, QPen pen, QBrush brush, QPainter::CompositionMode cm, bool antialiasing);
107 void drawPath(QPainterPath path, QPen pen, QBrush brush, QPainter::CompositionMode cm, bool antialiasing);
108
109 QPoint topLeft() { autoCrop(); return mBounds.topLeft(); }
110 QPoint topRight() { autoCrop(); return mBounds.topRight(); }
111 QPoint bottomLeft() { autoCrop(); return mBounds.bottomLeft(); }
112 QPoint bottomRight() { autoCrop(); return mBounds.bottomRight(); }
113 int left() { autoCrop(); return mBounds.left(); }
114 int right() { autoCrop(); return mBounds.right(); }
115 int top() { autoCrop(); return mBounds.top(); }
116 int bottom() { autoCrop(); return mBounds.bottom(); }
117 int width() { autoCrop(); return mBounds.width(); }
118 int height() { autoCrop(); return mBounds.height(); }
119 QSize size() { autoCrop(); return mBounds.size(); }
120
121 BitmapImage* scanToTransparent(BitmapImage* img, int threshold, bool redEnabled, bool greenEnabled, bool blueEnabled);
122
123 QRect& bounds() { autoCrop(); return mBounds; }
124
135 bool isMinimallyBounded() const { return mMinBound; }
136 void enableAutoCrop(bool b) { mEnableAutoCrop = b; }
137 void setOpacity(qreal opacity) { mOpacity = opacity; }
138 qreal getOpacity() const { return mOpacity; }
139
140 Status writeFile(const QString& filename);
141
156 static inline bool compareColor(QRgb newColor, QRgb oldColor, int tolerance, QHash<QRgb, bool> *cache)
157 {
158 // Handle trivial case
159 if (newColor == oldColor) return true;
160
161 if(cache && cache->contains(newColor)) return cache->value(newColor);
162
163 // Get Eulcidian distance between colors
164 // Not an accurate representation of human perception,
165 // but it's the best any image editing program ever does
166 int diffRed = static_cast<int>(qPow(qRed(oldColor) - qRed(newColor), 2));
167 int diffGreen = static_cast<int>(qPow(qGreen(oldColor) - qGreen(newColor), 2));
168 int diffBlue = static_cast<int>(qPow(qBlue(oldColor) - qBlue(newColor), 2));
169 // This may not be the best way to handle alpha since the other channels become less relevant as
170 // the alpha is reduces (ex. QColor(0,0,0,0) is the same as QColor(255,255,255,0))
171 int diffAlpha = static_cast<int>(qPow(qAlpha(oldColor) - qAlpha(newColor), 2));
172
173 bool isSimilar = (diffRed + diffGreen + diffBlue + diffAlpha) <= tolerance;
174
175 if(cache)
176 {
177 Q_ASSERT(cache->contains(isSimilar) ? isSimilar == (*cache)[newColor] : true);
178 (*cache)[newColor] = isSimilar;
179 }
180
181 return isSimilar;
182 }
183
184protected:
185 void updateBounds(QRect rectangle);
186 void extend(const QPoint& p);
187 void extend(QRect rectangle);
188
189 void setCompositionModeBounds(BitmapImage *source, QPainter::CompositionMode cm);
190 void setCompositionModeBounds(QRect sourceBounds, bool isSourceMinBounds, QPainter::CompositionMode cm);
191
192private:
193 QImage mImage;
194 QRect mBounds{0, 0, 0, 0};
195
197 bool mMinBound = true;
198 bool mEnableAutoCrop = false;
199
200 const int LOW_THRESHOLD = 30; // threshold for images to be given transparency
201 const int COLORDIFF = 5; // difference in color values to decide color
202 const int GRAYSCALEDIFF = 15; // difference in grasycale values to decide color
203
204 qreal mOpacity = 1.0;
205};
206
207#endif
BitmapImage
Definition: bitmapimage.h:28
BitmapImage::updateBounds
void updateBounds(QRect rectangle)
Update image bounds.
Definition: bitmapimage.cpp:300
BitmapImage::loadFile
void loadFile() override
Loads the backing image data from disk and into memory if it exists but hasn't been loaded yet.
Definition: bitmapimage.cpp:130
BitmapImage::mMinBound
bool mMinBound
Definition: bitmapimage.h:197
BitmapImage::isLoaded
bool isLoaded() const override
Checks whether the keyframe holds valid image data.
Definition: bitmapimage.cpp:148
BitmapImage::setCompositionModeBounds
void setCompositionModeBounds(BitmapImage *source, QPainter::CompositionMode cm)
Updates the bounds after a drawImage operation with the composition mode cm.
Definition: bitmapimage.cpp:361
BitmapImage::expandFill
static void expandFill(bool *fillPixels, const QRect &searchBounds, const QRect &maxBounds, int expand)
Finds all pixels closest to the input color and applies the input color to the image.
Definition: bitmapimage.cpp:1029
BitmapImage::autoCrop
void autoCrop()
Removes any transparent borders by reducing the boundaries.
Definition: bitmapimage.cpp:433
BitmapImage::compareColor
static bool compareColor(QRgb newColor, QRgb oldColor, int tolerance, QHash< QRgb, bool > *cache)
Compare colors for the purposes of flood filling.
Definition: bitmapimage.h:156
BitmapImage::isMinimallyBounded
bool isMinimallyBounded() const
Determines if the BitmapImage is minimally bounded.
Definition: bitmapimage.h:135
BitmapImage::unloadFile
void unloadFile() override
Unloads the image data from memory if there's valid backing data on disk and the latest state has bee...
Definition: bitmapimage.cpp:140
KeyFrame
Definition: keyframe.h:30
Status
Definition: pencilerror.h:40
TiledBuffer
Definition: tiledbuffer.h:50
QBrush
QColor
QHash
QHash::contains
bool contains(const Key &key) const const
QHash::value
const T value(const Key &key) const const
QImage
QPainter
QPainter::CompositionMode
CompositionMode
QPainterPath
QPen
QPoint
QPointF
QPointF::toPoint
QPoint toPoint() const const
QRect
QRect::bottom
int bottom() const const
QRect::bottomLeft
QPoint bottomLeft() const const
QRect::bottomRight
QPoint bottomRight() const const
QRect::contains
bool contains(const QRect &rectangle, bool proper) const const
QRect::height
int height() const const
QRect::left
int left() const const
QRect::right
int right() const const
QRect::size
QSize size() const const
QRect::top
int top() const const
QRect::topLeft
QPoint topLeft() const const
QRect::topRight
QPoint topRight() const const
QRect::width
int width() const const
QRectF
QRectF::toRect
QRect toRect() const const
QSize
QString
QTransform
Generated on Wed May 20 2026 06:16:32 for Pencil2D by doxygen 1.9.6 based on revision b8a30d7dfe4ff276bcca8087d5396d1507ed94fa