mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Issue #108: Add accessibility options in pdf reader
This commit is contained in:
210
Pdf4QtLib/sources/pdfcolorconvertor.cpp
Normal file
210
Pdf4QtLib/sources/pdfcolorconvertor.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
// Copyright (C) 2023 Jakub Melka
|
||||
//
|
||||
// This file is part of PDF4QT.
|
||||
//
|
||||
// PDF4QT is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// with the written consent of the copyright owner, any later version.
|
||||
//
|
||||
// PDF4QT 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 Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "pdfcolorconvertor.h"
|
||||
#include "pdfimageconversion.h"
|
||||
#include "pdfutils.h"
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
|
||||
PDFColorConvertor::PDFColorConvertor()
|
||||
{
|
||||
calculateSigmoidParams();
|
||||
}
|
||||
|
||||
bool PDFColorConvertor::isActive() const
|
||||
{
|
||||
return m_mode != Mode::Normal;
|
||||
}
|
||||
|
||||
void PDFColorConvertor::setMode(Mode mode)
|
||||
{
|
||||
m_mode = mode;
|
||||
}
|
||||
|
||||
QColor PDFColorConvertor::convert(QColor color, bool background, bool foreground) const
|
||||
{
|
||||
switch (m_mode)
|
||||
{
|
||||
case Mode::Normal:
|
||||
return color;
|
||||
|
||||
case Mode::InvertedColors:
|
||||
return invertColor(color);
|
||||
|
||||
case Mode::Grayscale:
|
||||
{
|
||||
int gray = qGray(color.red(), color.green(), color.blue());
|
||||
return QColor(gray, gray, gray, color.alpha());
|
||||
}
|
||||
|
||||
case Mode::HighContrast:
|
||||
{
|
||||
const float lightness = color.lightnessF();
|
||||
const float adjustedLightness = correctLigthnessBySigmoidFunction(lightness);
|
||||
QColor hslColor = color.toHsl();
|
||||
hslColor.setHslF(hslColor.hueF(), hslColor.saturationF(), adjustedLightness, color.alphaF());
|
||||
return hslColor.toRgb();
|
||||
}
|
||||
|
||||
case Mode::Bitonal:
|
||||
{
|
||||
const int lightness = color.lightness();
|
||||
QColor bitonalColor = (lightness >= m_bitonalThreshold) ? QColor(Qt::white) : QColor(Qt::black);
|
||||
bitonalColor.setAlpha(bitonalColor.alpha());
|
||||
return bitonalColor;
|
||||
}
|
||||
|
||||
case Mode::CustomColors:
|
||||
{
|
||||
if (background)
|
||||
{
|
||||
return m_backgroundColor;
|
||||
}
|
||||
|
||||
if (foreground)
|
||||
{
|
||||
return m_foregroundColor;
|
||||
}
|
||||
|
||||
const float lightness = color.lightnessF();
|
||||
QColor hslColor = m_foregroundColor;
|
||||
hslColor.setHslF(hslColor.hueF(), hslColor.saturationF(), lightness, color.alphaF());
|
||||
return hslColor.toRgb();
|
||||
}
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
QImage PDFColorConvertor::convert(QImage image) const
|
||||
{
|
||||
switch (m_mode)
|
||||
{
|
||||
case Mode::Normal:
|
||||
return image;
|
||||
|
||||
case Mode::InvertedColors:
|
||||
{
|
||||
image.invertPixels(QImage::InvertRgb);
|
||||
return image;
|
||||
}
|
||||
|
||||
case Mode::Grayscale:
|
||||
{
|
||||
QImage alpha = image.convertedTo(QImage::Format_Alpha8);
|
||||
QImage grayscaleImage = image.convertedTo(QImage::Format_Grayscale8);
|
||||
QImage resultImage = grayscaleImage;
|
||||
resultImage = resultImage.convertedTo(QImage::Format_ARGB32);
|
||||
resultImage.setAlphaChannel(std::move(alpha));
|
||||
return resultImage;
|
||||
}
|
||||
|
||||
case Mode::Bitonal:
|
||||
{
|
||||
PDFImageConversion imageConversion;
|
||||
imageConversion.setConversionMethod(PDFImageConversion::ConversionMethod::Automatic);
|
||||
imageConversion.setImage(image);
|
||||
|
||||
if (imageConversion.convert())
|
||||
{
|
||||
return imageConversion.getConvertedImage();
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
case Mode::HighContrast:
|
||||
case Mode::CustomColors:
|
||||
{
|
||||
for (int row = 0; row < image.height(); ++row)
|
||||
{
|
||||
for (int column = 0; column < image.width(); ++column)
|
||||
{
|
||||
QColor color = image.pixelColor(column, row);
|
||||
QColor adjustedColor = convert(color, false, false);
|
||||
image.setPixelColor(column, row, adjustedColor);
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void PDFColorConvertor::setHighContrastBrightnessFactor(float factor)
|
||||
{
|
||||
m_sigmoidParamC = factor;
|
||||
calculateSigmoidParams();
|
||||
}
|
||||
|
||||
float PDFColorConvertor::correctLigthnessBySigmoidFunction(float lightness) const
|
||||
{
|
||||
const float adjustedLightness = sigmoidFunction(lightness);
|
||||
const float normalizedLightness = (adjustedLightness - m_sigmoidParamC_Black) / m_sigmoidParamC_Range;
|
||||
return qBound(0.0f, normalizedLightness, 1.0f);
|
||||
}
|
||||
|
||||
float PDFColorConvertor::sigmoidFunction(float value) const
|
||||
{
|
||||
return 1.0f / (1.0f + std::expf(-m_sigmoidParamC * (value - 0.5f)));
|
||||
}
|
||||
|
||||
float PDFColorConvertor::sigmoidParamC_Black() const
|
||||
{
|
||||
return sigmoidFunction(0.0);
|
||||
}
|
||||
|
||||
float PDFColorConvertor::sigmoidParamC_White() const
|
||||
{
|
||||
return sigmoidFunction(1.0);
|
||||
}
|
||||
|
||||
float PDFColorConvertor::sigmoidParamC_Range() const
|
||||
{
|
||||
return sigmoidParamC_White() - sigmoidParamC_Black();
|
||||
}
|
||||
|
||||
void PDFColorConvertor::calculateSigmoidParams()
|
||||
{
|
||||
m_sigmoidParamC_Black = sigmoidParamC_Black();
|
||||
m_sigmoidParamC_White = sigmoidParamC_White();
|
||||
m_sigmoidParamC_Range = sigmoidParamC_Range();
|
||||
}
|
||||
|
||||
int PDFColorConvertor::getBitonalThreshold() const
|
||||
{
|
||||
return m_bitonalThreshold;
|
||||
}
|
||||
|
||||
void PDFColorConvertor::setBitonalThreshold(int newBitonalThreshold)
|
||||
{
|
||||
m_bitonalThreshold = newBitonalThreshold;
|
||||
}
|
||||
|
||||
} // namespace pdf
|
Reference in New Issue
Block a user