mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Display of ink coverage
This commit is contained in:
@ -90,6 +90,23 @@ PDFColorComponent PDFFloatBitmap::getPixelInkCoverage(size_t x, size_t y) const
|
||||
return inkCoverage;
|
||||
}
|
||||
|
||||
PDFFloatBitmap PDFFloatBitmap::getInkCoverageBitmap() const
|
||||
{
|
||||
PDFFloatBitmap result(getWidth(), getHeight(), PDFPixelFormat::createFormat(1, 0, false, true, false));
|
||||
|
||||
for (size_t y = 0; y < getHeight(); ++y)
|
||||
{
|
||||
for (size_t x = 0; x < getWidth(); ++x)
|
||||
{
|
||||
PDFColorComponent coverage = getPixelInkCoverage(x, y);
|
||||
PDFColorBuffer targetProcessColorBuffer = result.getPixel(x, y);
|
||||
targetProcessColorBuffer[0] = coverage;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const PDFColorComponent* PDFFloatBitmap::begin() const
|
||||
{
|
||||
return m_data.data();
|
||||
|
@ -160,6 +160,10 @@ public:
|
||||
/// Returns ink coverage
|
||||
PDFColorComponent getPixelInkCoverage(size_t x, size_t y) const;
|
||||
|
||||
/// Returns ink coverage bitmap. Bitmap consists of one color channel,
|
||||
/// which consists of ink coverage.
|
||||
PDFFloatBitmap getInkCoverageBitmap() const;
|
||||
|
||||
const PDFColorComponent* begin() const;
|
||||
const PDFColorComponent* end() const;
|
||||
|
||||
|
@ -518,4 +518,43 @@ QString PDFSysUtils::getUserName()
|
||||
return userName;
|
||||
}
|
||||
|
||||
PDFColorScale::PDFColorScale(PDFReal min, PDFReal max) :
|
||||
m_min(min),
|
||||
m_max(max)
|
||||
{
|
||||
m_colorScales = {
|
||||
Qt::blue,
|
||||
Qt::cyan,
|
||||
Qt::green,
|
||||
Qt::yellow,
|
||||
Qt::red
|
||||
};
|
||||
}
|
||||
|
||||
QColor PDFColorScale::map(PDFReal value) const
|
||||
{
|
||||
PDFReal correctedValue = qBound(m_min, value, m_max);
|
||||
PDFReal intervalValue = interpolate(correctedValue, m_min, m_max, 0.0, PDFReal(m_colorScales.size() - 1));
|
||||
PDFReal indexValue = qFloor(intervalValue);
|
||||
int index = indexValue;
|
||||
PDFReal fractionValue = intervalValue - index;
|
||||
|
||||
if (index == int(m_colorScales.size()) - 1)
|
||||
{
|
||||
--index;
|
||||
fractionValue = 1.0;
|
||||
}
|
||||
|
||||
Q_ASSERT(index + 1 < m_colorScales.size());
|
||||
|
||||
const QColor& leftValue = m_colorScales[index];
|
||||
const QColor& rightValue = m_colorScales[index + 1];
|
||||
|
||||
qreal r = (1.0 - fractionValue) * leftValue.redF() + fractionValue * rightValue.redF();
|
||||
qreal g = (1.0 - fractionValue) * leftValue.greenF() + fractionValue * rightValue.greenF();
|
||||
qreal b = (1.0 - fractionValue) * leftValue.blueF() + fractionValue * rightValue.blueF();
|
||||
|
||||
return QColor::fromRgbF(r, g, b);
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
@ -806,6 +806,21 @@ QDataStream& operator<<(QDataStream& stream, const std::set<T>& set)
|
||||
return stream;
|
||||
}
|
||||
|
||||
/// Color scale represents hot-to-cold color scale. It maps value
|
||||
/// to the color from blue trough green to red.
|
||||
class Pdf4QtLIBSHARED_EXPORT PDFColorScale
|
||||
{
|
||||
public:
|
||||
explicit PDFColorScale(PDFReal min, PDFReal max);
|
||||
|
||||
QColor map(PDFReal value) const;
|
||||
|
||||
private:
|
||||
std::vector<QColor> m_colorScales;
|
||||
PDFReal m_min;
|
||||
PDFReal m_max;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
||||
#endif // PDFUTILS_H
|
||||
|
@ -57,6 +57,7 @@ void OutputPreviewWidget::clear()
|
||||
m_inkCoverageMM.dirty();
|
||||
m_alarmCoverageImage.dirty();
|
||||
m_alarmRichBlackImage.dirty();
|
||||
m_inkCoverageImage.dirty();
|
||||
update();
|
||||
}
|
||||
|
||||
@ -78,6 +79,7 @@ void OutputPreviewWidget::setPageImage(QImage image, pdf::PDFFloatBitmapWithColo
|
||||
m_inkCoverageMM.dirty();
|
||||
m_alarmCoverageImage.dirty();
|
||||
m_alarmRichBlackImage.dirty();
|
||||
m_inkCoverageImage.dirty();
|
||||
|
||||
buildInfoBoxItems();
|
||||
update();
|
||||
@ -135,7 +137,15 @@ void OutputPreviewWidget::paintEvent(QPaintEvent* event)
|
||||
}
|
||||
|
||||
case InkCoverage:
|
||||
{
|
||||
const InkCoverageInfo& image = getInkCoverageInfo();
|
||||
if (!image.image.isNull())
|
||||
{
|
||||
painter.translate(0, (pageImageRect.height() - image.image.height()) / 2);
|
||||
painter.drawImage(pageImageRect.topLeft(), image.image);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
@ -490,6 +500,11 @@ const OutputPreviewWidget::AlarmImageInfo& OutputPreviewWidget::getAlarmRichBlac
|
||||
return m_alarmRichBlackImage.get(this, &OutputPreviewWidget::getAlarmRichBlackImageImpl);
|
||||
}
|
||||
|
||||
const OutputPreviewWidget::InkCoverageInfo& OutputPreviewWidget::getInkCoverageInfo() const
|
||||
{
|
||||
return m_inkCoverageImage.get(this, &OutputPreviewWidget::getInkCoverageInfoImpl);
|
||||
}
|
||||
|
||||
std::vector<pdf::PDFColorComponent> OutputPreviewWidget::getInkCoverageImpl() const
|
||||
{
|
||||
std::vector<pdf::PDFColorComponent> result;
|
||||
@ -611,6 +626,47 @@ OutputPreviewWidget::AlarmImageInfo OutputPreviewWidget::getAlarmRichBlackImageI
|
||||
return alarmImage;
|
||||
}
|
||||
|
||||
OutputPreviewWidget::InkCoverageInfo OutputPreviewWidget::getInkCoverageInfoImpl() const
|
||||
{
|
||||
InkCoverageInfo coverageInfo;
|
||||
coverageInfo.minValue = 0.0f;
|
||||
coverageInfo.maxValue = 1.0f;
|
||||
|
||||
pdf::PDFFloatBitmap inkCoverageBitmap = m_originalProcessBitmap.getInkCoverageBitmap();
|
||||
|
||||
int width = int(inkCoverageBitmap.getWidth());
|
||||
int height = int(inkCoverageBitmap.getHeight());
|
||||
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
pdf::PDFColorBuffer buffer = inkCoverageBitmap.getPixel(x, y);
|
||||
const pdf::PDFColorComponent coverage = buffer[0];
|
||||
coverageInfo.maxValue = qMax(coverage, coverageInfo.maxValue);
|
||||
}
|
||||
}
|
||||
|
||||
pdf::PDFColorScale colorScale(coverageInfo.minValue, coverageInfo.maxValue);
|
||||
coverageInfo.image = QImage(width, height, QImage::Format_RGBX8888);
|
||||
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
pdf::PDFColorBuffer buffer = inkCoverageBitmap.getPixel(x, y);
|
||||
const pdf::PDFColorComponent coverage = buffer[0];
|
||||
|
||||
coverageInfo.image.setPixelColor(x, y, colorScale.map(coverage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return coverageInfo;
|
||||
}
|
||||
|
||||
pdf::PDFColorComponent OutputPreviewWidget::getRichBlackLimit() const
|
||||
{
|
||||
return m_richBlackLimit;
|
||||
|
@ -95,13 +95,22 @@ private:
|
||||
pdf::PDFColorComponent areaInvalid = 0.0f;
|
||||
};
|
||||
|
||||
struct InkCoverageInfo
|
||||
{
|
||||
QImage image;
|
||||
pdf::PDFColorComponent minValue = 0.0f;
|
||||
pdf::PDFColorComponent maxValue = 0.0f;
|
||||
};
|
||||
|
||||
const std::vector<pdf::PDFColorComponent>& getInkCoverage() const;
|
||||
const AlarmImageInfo& getAlarmCoverageImage() const;
|
||||
const AlarmImageInfo& getAlarmRichBlackImage() const;
|
||||
const InkCoverageInfo& getInkCoverageInfo() const;
|
||||
|
||||
std::vector<pdf::PDFColorComponent> getInkCoverageImpl() const;
|
||||
AlarmImageInfo getAlarmCoverageImageImpl() const;
|
||||
AlarmImageInfo getAlarmRichBlackImageImpl() const;
|
||||
InkCoverageInfo getInkCoverageInfoImpl() const;
|
||||
|
||||
enum InfoBoxStyle
|
||||
{
|
||||
@ -139,6 +148,7 @@ private:
|
||||
mutable pdf::PDFCachedItem<std::vector<pdf::PDFColorComponent>> m_inkCoverageMM;
|
||||
mutable pdf::PDFCachedItem<AlarmImageInfo> m_alarmCoverageImage;
|
||||
mutable pdf::PDFCachedItem<AlarmImageInfo> m_alarmRichBlackImage;
|
||||
mutable pdf::PDFCachedItem<InkCoverageInfo> m_inkCoverageImage;
|
||||
|
||||
QImage m_pageImage;
|
||||
pdf::PDFFloatBitmapWithColorSpace m_originalProcessBitmap;
|
||||
|
Reference in New Issue
Block a user