MicroPythonBitmapTool/MonoTools.cpp

135 wiersze
4.9 KiB
C++

//
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
#include "MonoTools.hpp"
MonoTools::MonoTools(MonoTools::UnitOrientation unitOrientation, MonoTools::BitDirection bitDirection, int unitSize)
: _unitOrientation(unitOrientation), _bitDirection(bitDirection), _unitSize(unitSize)
{
}
void MonoTools::addMonoLegendData(LegendDataPtr data, OverlayMode mode) const
{
if (mode == OverlayMode::BitAssigments) {
data->addEntry(colorBitAssignment1, colorBitAssignment2, QObject::tr("Bit Assignment"));
} else {
data->addEntry(colorPixelInterpretation, QObject::tr("Pixel Interpretation"));
}
}
QSize MonoTools::monoGeneratedSize(const QSize &imageSize, const QVariantMap&) const
{
if (_unitOrientation == UnitOrientation::Vertical) {
if ((imageSize.height() % _unitSize) != 0) {
return QSize(imageSize.width(), ((imageSize.height()/_unitSize)+1)*_unitSize);
} else {
return imageSize;
}
} else {
if ((imageSize.width() % _unitSize) != 0) {
return QSize(((imageSize.width()/_unitSize)+1)*_unitSize, imageSize.height());
} else {
return imageSize;
}
}
}
void MonoTools::monoPaintOverlay(OverlayPainter &p, OverlayMode mode, const QImage &image, const QVariantMap&) const
{
if (mode == OverlayMode::BitAssigments) {
const auto bitL = (_bitDirection == BitDirection::LSB ? "0" : QString::number(_unitSize-1));
const auto bitH = (_bitDirection == BitDirection::LSB ? QString::number(_unitSize-1) : "0");
bool colorFlag = false;
if (_unitOrientation == UnitOrientation::Vertical) {
for (int y = 0; y < p.imageSize().height(); y += _unitSize) {
for (int x = 0; x < p.imageSize().width(); ++x) {
QRect rect(x, y, 1, _unitSize);
if (p.arePixelUpdated(rect)) {
const auto color = colorFlag ? colorBitAssignment1 : colorBitAssignment2;
p.drawPixelOutline(rect, color, 1);
p.drawPixelText(QRect(x, y, 1, 1), color, bitL);
p.drawPixelText(QRect(x, y+_unitSize-1, 1, 1), color, bitH);
}
colorFlag = !colorFlag;
}
if (p.imageSize().width() % 2 == 0) {
colorFlag = !colorFlag;
}
}
} else {
for (int y = 0; y < p.imageSize().height(); ++y) {
for (int x = 0; x < p.imageSize().width(); x += _unitSize) {
QRect rect(x, y, _unitSize, 1);
if (p.arePixelUpdated(rect)) {
const auto color = colorFlag ? colorBitAssignment1 : colorBitAssignment2;
p.drawPixelOutline(rect, color, 1);
p.drawPixelText(QRect(x, y, 1, 1), color, bitH);
p.drawPixelText(QRect(x+_unitSize-1, y, 1, 1), color, bitL);
}
colorFlag = !colorFlag;
}
if ((p.imageSize().width()/_unitSize) % 2 == 0) {
colorFlag = !colorFlag;
}
}
}
} else if (mode == OverlayMode::PixelInterpretation) {
for (int y = 0; y < p.generatedSize().height(); ++y) {
for (int x = 0; x < p.generatedSize().width(); ++x) {
auto text = (getPixel(x, y, image) ? "1" : "0");
const QRect rect(x, y, 1, 1);
if (p.arePixelUpdated(rect)) {
p.drawPixelText(rect, colorPixelInterpretation, text);
}
}
}
}
}
bool MonoTools::getPixel(int x, int y, const QImage &image)
{
if (x < 0 || y < 0 || x >= image.width() || y >= image.height()) {
return false;
}
auto color = image.pixelColor(x, y);
float h, s, l, a;
color.getHslF(&h, &s, &l, &a);
if (a < 0.5) {
return false;
}
return l < 0.5;
}
uint32_t MonoTools::readUnit(int x, int y, int dx, int dy, int count, const QImage &image)
{
uint32_t result = 0;
for (int i = 0; i < count; ++i) {
result <<= 1;
if (getPixel(x, y, image)) {
result |= 0b1;
}
x += dx;
y += dy;
}
return result;
}