mirror of
https://github.com/qgis/QGIS.git
synced 2025-11-22 00:14:55 -05:00
feat(CMYK): add API color model and profile methods to project
API allows to define a color model without a color space. If both are set, consistency between defined color model and color space one is checked (only in Qt version 6.8.0 or greater because it's not possible to retrieve color model from color space before that)
This commit is contained in:
parent
7f699bcfc3
commit
7e527d182b
@ -5144,3 +5144,9 @@ Qgis.SensorThingsEntity.MultiDatastream.__doc__ = "A MultiDatastream groups a co
|
||||
Qgis.SensorThingsEntity.__doc__ = "OGC SensorThings API entity types.\n\n.. versionadded:: 3.36\n\n" + '* ``Invalid``: ' + Qgis.SensorThingsEntity.Invalid.__doc__ + '\n' + '* ``Thing``: ' + Qgis.SensorThingsEntity.Thing.__doc__ + '\n' + '* ``Location``: ' + Qgis.SensorThingsEntity.Location.__doc__ + '\n' + '* ``HistoricalLocation``: ' + Qgis.SensorThingsEntity.HistoricalLocation.__doc__ + '\n' + '* ``Datastream``: ' + Qgis.SensorThingsEntity.Datastream.__doc__ + '\n' + '* ``Sensor``: ' + Qgis.SensorThingsEntity.Sensor.__doc__ + '\n' + '* ``ObservedProperty``: ' + Qgis.SensorThingsEntity.ObservedProperty.__doc__ + '\n' + '* ``Observation``: ' + Qgis.SensorThingsEntity.Observation.__doc__ + '\n' + '* ``FeatureOfInterest``: ' + Qgis.SensorThingsEntity.FeatureOfInterest.__doc__ + '\n' + '* ``MultiDatastream``: ' + Qgis.SensorThingsEntity.MultiDatastream.__doc__
|
||||
# --
|
||||
Qgis.SensorThingsEntity.baseClass = Qgis
|
||||
# monkey patching scoped based enum
|
||||
Qgis.ColorModel.Rgb.__doc__ = ""
|
||||
Qgis.ColorModel.Cmyk.__doc__ = ""
|
||||
Qgis.ColorModel.__doc__ = "Color model types\n\n.. versionadded:: 3.40\n\n" + '* ``Rgb``: ' + Qgis.ColorModel.Rgb.__doc__ + '\n' + '* ``Cmyk``: ' + Qgis.ColorModel.Cmyk.__doc__
|
||||
# --
|
||||
Qgis.ColorModel.baseClass = Qgis
|
||||
|
||||
@ -139,6 +139,71 @@ Sets the style database to use for the project style.
|
||||
Returns the style database to use for project specific styles.
|
||||
|
||||
.. seealso:: :py:func:`setProjectStyle`
|
||||
%End
|
||||
|
||||
void setColorModel( Qgis::ColorModel colorModel );
|
||||
%Docstring
|
||||
Set project ``colorModel``
|
||||
|
||||
It would serve as default color model when selecting a color in the whole application.
|
||||
Any color defined in a different color model than the one specified here will be converted to
|
||||
this color model when exporting a layout.
|
||||
|
||||
If a color space has already been set and its color model differs from ``colorModel``, project
|
||||
color space is set to invalid one. :py:func:`setColorSpace` colorSpace()
|
||||
|
||||
defaults to :py:class:`Qgis`.ColorModel.Rgb
|
||||
|
||||
.. seealso:: :py:func:`colorModel`
|
||||
|
||||
.. versionadded:: 3.40
|
||||
%End
|
||||
|
||||
Qgis::ColorModel colorModel() const;
|
||||
%Docstring
|
||||
Returns project color model
|
||||
|
||||
Used as default color model when selecting a color in the whole application.
|
||||
Any color defined in a different color model than the returned will be converted to
|
||||
this color model when exporting a layout
|
||||
|
||||
defaults to :py:class:`Qgis`.ColorModel.Rgb
|
||||
|
||||
.. seealso:: :py:func:`setColorModel`
|
||||
|
||||
.. versionadded:: 3.40
|
||||
%End
|
||||
|
||||
void setColorSpace( const QColorSpace &colorSpace );
|
||||
%Docstring
|
||||
Set project current ``colorSpace``. ``colorSpace`` must be a valid RGB or CMYK color space.
|
||||
Color space ICC profile will be added as a project attached file.
|
||||
|
||||
Project color space will be added to PDF layout export if defined (meaning different from
|
||||
the default invalid QColorSpace).
|
||||
|
||||
If a color model has already been set and it differs from ``colorSpace`` color model, project
|
||||
color model is set to ``colorSpace`` one. :py:func:`setColorModel` colorModel()
|
||||
|
||||
defaults to invalid color space
|
||||
|
||||
.. seealso:: :py:func:`colorSpace`
|
||||
|
||||
.. versionadded:: 3.40
|
||||
%End
|
||||
|
||||
QColorSpace colorSpace() const;
|
||||
%Docstring
|
||||
Returns current project color space.
|
||||
|
||||
Project color space will be added to PDF layout export if defined (meaning different from
|
||||
the default invalid QColorSpace).
|
||||
|
||||
defaults to invalid color space
|
||||
|
||||
.. seealso:: :py:func:`setColorSpace`
|
||||
|
||||
.. versionadded:: 3.40
|
||||
%End
|
||||
|
||||
bool readXml( const QDomElement &element, const QgsReadWriteContext &context, Qgis::ProjectReadFlags flags = Qgis::ProjectReadFlags() );
|
||||
|
||||
@ -2886,6 +2886,12 @@ The development version
|
||||
MultiDatastream,
|
||||
};
|
||||
|
||||
enum class ColorModel /BaseType=IntEnum/
|
||||
{
|
||||
Rgb,
|
||||
Cmyk
|
||||
};
|
||||
|
||||
static const double DEFAULT_SEARCH_RADIUS_MM;
|
||||
|
||||
static const float DEFAULT_MAPTOPIXEL_THRESHOLD;
|
||||
|
||||
@ -81,6 +81,16 @@ An invalid color will be returned if the color could not be read.
|
||||
.. seealso:: :py:func:`colorToString`
|
||||
%End
|
||||
|
||||
static QColorSpace iccProfile( const QString &iccProfileFilePath, QString &errorMsg );
|
||||
%Docstring
|
||||
Load ``iccProfileFilePath`` and returns associated color space.
|
||||
If an error occurred, an invalid color space is returned and ``errorMsg`` is updated with error
|
||||
message
|
||||
%End
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
|
||||
@ -5062,6 +5062,12 @@ Qgis.SensorThingsEntity.MultiDatastream.__doc__ = "A MultiDatastream groups a co
|
||||
Qgis.SensorThingsEntity.__doc__ = "OGC SensorThings API entity types.\n\n.. versionadded:: 3.36\n\n" + '* ``Invalid``: ' + Qgis.SensorThingsEntity.Invalid.__doc__ + '\n' + '* ``Thing``: ' + Qgis.SensorThingsEntity.Thing.__doc__ + '\n' + '* ``Location``: ' + Qgis.SensorThingsEntity.Location.__doc__ + '\n' + '* ``HistoricalLocation``: ' + Qgis.SensorThingsEntity.HistoricalLocation.__doc__ + '\n' + '* ``Datastream``: ' + Qgis.SensorThingsEntity.Datastream.__doc__ + '\n' + '* ``Sensor``: ' + Qgis.SensorThingsEntity.Sensor.__doc__ + '\n' + '* ``ObservedProperty``: ' + Qgis.SensorThingsEntity.ObservedProperty.__doc__ + '\n' + '* ``Observation``: ' + Qgis.SensorThingsEntity.Observation.__doc__ + '\n' + '* ``FeatureOfInterest``: ' + Qgis.SensorThingsEntity.FeatureOfInterest.__doc__ + '\n' + '* ``MultiDatastream``: ' + Qgis.SensorThingsEntity.MultiDatastream.__doc__
|
||||
# --
|
||||
Qgis.SensorThingsEntity.baseClass = Qgis
|
||||
# monkey patching scoped based enum
|
||||
Qgis.ColorModel.Rgb.__doc__ = ""
|
||||
Qgis.ColorModel.Cmyk.__doc__ = ""
|
||||
Qgis.ColorModel.__doc__ = "Color model types\n\n.. versionadded:: 3.40\n\n" + '* ``Rgb``: ' + Qgis.ColorModel.Rgb.__doc__ + '\n' + '* ``Cmyk``: ' + Qgis.ColorModel.Cmyk.__doc__
|
||||
# --
|
||||
Qgis.ColorModel.baseClass = Qgis
|
||||
from enum import Enum
|
||||
|
||||
|
||||
|
||||
@ -139,6 +139,71 @@ Sets the style database to use for the project style.
|
||||
Returns the style database to use for project specific styles.
|
||||
|
||||
.. seealso:: :py:func:`setProjectStyle`
|
||||
%End
|
||||
|
||||
void setColorModel( Qgis::ColorModel colorModel );
|
||||
%Docstring
|
||||
Set project ``colorModel``
|
||||
|
||||
It would serve as default color model when selecting a color in the whole application.
|
||||
Any color defined in a different color model than the one specified here will be converted to
|
||||
this color model when exporting a layout.
|
||||
|
||||
If a color space has already been set and its color model differs from ``colorModel``, project
|
||||
color space is set to invalid one. :py:func:`setColorSpace` colorSpace()
|
||||
|
||||
defaults to :py:class:`Qgis`.ColorModel.Rgb
|
||||
|
||||
.. seealso:: :py:func:`colorModel`
|
||||
|
||||
.. versionadded:: 3.40
|
||||
%End
|
||||
|
||||
Qgis::ColorModel colorModel() const;
|
||||
%Docstring
|
||||
Returns project color model
|
||||
|
||||
Used as default color model when selecting a color in the whole application.
|
||||
Any color defined in a different color model than the returned will be converted to
|
||||
this color model when exporting a layout
|
||||
|
||||
defaults to :py:class:`Qgis`.ColorModel.Rgb
|
||||
|
||||
.. seealso:: :py:func:`setColorModel`
|
||||
|
||||
.. versionadded:: 3.40
|
||||
%End
|
||||
|
||||
void setColorSpace( const QColorSpace &colorSpace );
|
||||
%Docstring
|
||||
Set project current ``colorSpace``. ``colorSpace`` must be a valid RGB or CMYK color space.
|
||||
Color space ICC profile will be added as a project attached file.
|
||||
|
||||
Project color space will be added to PDF layout export if defined (meaning different from
|
||||
the default invalid QColorSpace).
|
||||
|
||||
If a color model has already been set and it differs from ``colorSpace`` color model, project
|
||||
color model is set to ``colorSpace`` one. :py:func:`setColorModel` colorModel()
|
||||
|
||||
defaults to invalid color space
|
||||
|
||||
.. seealso:: :py:func:`colorSpace`
|
||||
|
||||
.. versionadded:: 3.40
|
||||
%End
|
||||
|
||||
QColorSpace colorSpace() const;
|
||||
%Docstring
|
||||
Returns current project color space.
|
||||
|
||||
Project color space will be added to PDF layout export if defined (meaning different from
|
||||
the default invalid QColorSpace).
|
||||
|
||||
defaults to invalid color space
|
||||
|
||||
.. seealso:: :py:func:`setColorSpace`
|
||||
|
||||
.. versionadded:: 3.40
|
||||
%End
|
||||
|
||||
bool readXml( const QDomElement &element, const QgsReadWriteContext &context, Qgis::ProjectReadFlags flags = Qgis::ProjectReadFlags() );
|
||||
|
||||
@ -2886,6 +2886,12 @@ The development version
|
||||
MultiDatastream,
|
||||
};
|
||||
|
||||
enum class ColorModel
|
||||
{
|
||||
Rgb,
|
||||
Cmyk
|
||||
};
|
||||
|
||||
static const double DEFAULT_SEARCH_RADIUS_MM;
|
||||
|
||||
static const float DEFAULT_MAPTOPIXEL_THRESHOLD;
|
||||
|
||||
@ -81,6 +81,16 @@ An invalid color will be returned if the color could not be read.
|
||||
.. seealso:: :py:func:`colorToString`
|
||||
%End
|
||||
|
||||
static QColorSpace iccProfile( const QString &iccProfileFilePath, QString &errorMsg );
|
||||
%Docstring
|
||||
Load ``iccProfileFilePath`` and returns associated color space.
|
||||
If an error occurred, an invalid color space is returned and ``errorMsg`` is updated with error
|
||||
message
|
||||
%End
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgscolorutils.h"
|
||||
#include "qgsprojectstylesettings.h"
|
||||
#include "qgis.h"
|
||||
#include "qgsproject.h"
|
||||
@ -25,6 +26,7 @@
|
||||
#include "qgstextformat.h"
|
||||
#include "qgsstyle.h"
|
||||
#include "qgscombinedstylemodel.h"
|
||||
#include "qgsxmlutils.h"
|
||||
|
||||
#include <QDomElement>
|
||||
|
||||
@ -170,6 +172,7 @@ bool QgsProjectStyleSettings::readXml( const QDomElement &element, const QgsRead
|
||||
{
|
||||
mRandomizeDefaultSymbolColor = element.attribute( QStringLiteral( "RandomizeDefaultSymbolColor" ), QStringLiteral( "0" ) ).toInt();
|
||||
mDefaultSymbolOpacity = element.attribute( QStringLiteral( "DefaultSymbolOpacity" ), QStringLiteral( "1.0" ) ).toDouble();
|
||||
mColorModel = QgsXmlUtils::readFlagAttribute( element, QStringLiteral( "colorModel" ), Qgis::ColorModel::Rgb );
|
||||
|
||||
QDomElement elem = element.firstChildElement( QStringLiteral( "markerSymbol" ) );
|
||||
if ( !elem.isNull() )
|
||||
@ -259,6 +262,15 @@ bool QgsProjectStyleSettings::readXml( const QDomElement &element, const QgsRead
|
||||
}
|
||||
}
|
||||
|
||||
const QString iccProfileId = element.attribute( QStringLiteral( "iccProfileId" ) );
|
||||
mIccProfileFilePath = mProject ? mProject->resolveAttachmentIdentifier( iccProfileId ) : QString();
|
||||
if ( !mIccProfileFilePath.isEmpty() )
|
||||
{
|
||||
QString errorMsg;
|
||||
QColorSpace colorSpace = QgsColorUtils::iccProfile( mIccProfileFilePath, errorMsg );
|
||||
setColorSpace( colorSpace );
|
||||
}
|
||||
|
||||
emit styleDatabasesChanged();
|
||||
|
||||
return true;
|
||||
@ -271,6 +283,10 @@ QDomElement QgsProjectStyleSettings::writeXml( QDomDocument &doc, const QgsReadW
|
||||
element.setAttribute( QStringLiteral( "RandomizeDefaultSymbolColor" ), mRandomizeDefaultSymbolColor ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
|
||||
element.setAttribute( QStringLiteral( "DefaultSymbolOpacity" ), QString::number( mDefaultSymbolOpacity ) );
|
||||
|
||||
const QMetaEnum metaEnum = QMetaEnum::fromType<Qgis::ColorModel>();
|
||||
const QString colorModel( metaEnum.valueToKeys( static_cast<int>( mColorModel ) ) );
|
||||
element.setAttribute( QStringLiteral( "colorModel" ), colorModel );
|
||||
|
||||
if ( mDefaultMarkerSymbol )
|
||||
{
|
||||
QDomElement markerSymbolElem = doc.createElement( QStringLiteral( "markerSymbol" ) );
|
||||
@ -320,6 +336,8 @@ QDomElement QgsProjectStyleSettings::writeXml( QDomDocument &doc, const QgsReadW
|
||||
element.setAttribute( QStringLiteral( "projectStyleId" ), mProject->attachmentIdentifier( mProjectStyle->fileName() ) );
|
||||
}
|
||||
|
||||
element.setAttribute( QStringLiteral( "iccProfileId" ), mProject->attachmentIdentifier( mIccProfileFilePath ) );
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
@ -440,7 +458,66 @@ QgsCombinedStyleModel *QgsProjectStyleSettings::combinedStyleModel()
|
||||
return mCombinedStyleModel;
|
||||
}
|
||||
|
||||
void QgsProjectStyleSettings::setColorModel( Qgis::ColorModel colorModel )
|
||||
{
|
||||
mColorModel = colorModel;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||
if ( mColorSpace.isValid() && QgsColorUtils::toColorModel( mColorSpace.colorModel() ) != colorModel )
|
||||
{
|
||||
setColorSpace( QColorSpace() );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Qgis::ColorModel QgsProjectStyleSettings::colorModel() const
|
||||
{
|
||||
return mColorModel;
|
||||
}
|
||||
|
||||
void QgsProjectStyleSettings::setColorSpace( const QColorSpace &colorSpace )
|
||||
{
|
||||
if ( !mProject )
|
||||
{
|
||||
QgsDebugError( "Impossible to attach ICC profile, no project defined" );
|
||||
return;
|
||||
}
|
||||
|
||||
auto clearIccProfile = [this]()
|
||||
{
|
||||
mProject->removeAttachedFile( mIccProfileFilePath );
|
||||
mIccProfileFilePath.clear();
|
||||
mColorSpace = QColorSpace();
|
||||
};
|
||||
|
||||
if ( !mIccProfileFilePath.isEmpty() )
|
||||
clearIccProfile();
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||
bool ok;
|
||||
Qgis::ColorModel colorModel = QgsColorUtils::toColorModel( colorSpace.colorModel(), &ok );
|
||||
mColorSpace = ok ? colorSpace : QColorSpace();
|
||||
#else
|
||||
mColorSpace = colorSpace;
|
||||
#endif
|
||||
|
||||
if ( !mColorSpace.isValid() )
|
||||
return;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||
if ( colorModel != mColorModel )
|
||||
mColorModel = colorModel;
|
||||
#endif
|
||||
|
||||
mIccProfileFilePath = mProject->createAttachedFile( QStringLiteral( "profile.icc" ) );
|
||||
QFile file( mIccProfileFilePath );
|
||||
if ( !file.open( QIODevice::WriteOnly ) || file.write( colorSpace.iccProfile() ) < 0 )
|
||||
clearIccProfile();
|
||||
}
|
||||
|
||||
QColorSpace QgsProjectStyleSettings::colorSpace() const
|
||||
{
|
||||
return mColorSpace;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
|
||||
#include <memory.h>
|
||||
#include <QAbstractListModel>
|
||||
#include <QColorSpace>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QPointer>
|
||||
|
||||
@ -144,6 +145,67 @@ class CORE_EXPORT QgsProjectStyleSettings : public QObject
|
||||
*/
|
||||
QgsStyle *projectStyle();
|
||||
|
||||
/**
|
||||
* Set project \a colorModel
|
||||
*
|
||||
* It would serve as default color model when selecting a color in the whole application.
|
||||
* Any color defined in a different color model than the one specified here will be converted to
|
||||
* this color model when exporting a layout.
|
||||
*
|
||||
* If a color space has already been set and its color model differs from \a colorModel, project
|
||||
* color space is set to invalid one. \see setColorSpace() colorSpace()
|
||||
*
|
||||
* defaults to Qgis::ColorModel::Rgb
|
||||
*
|
||||
* \see colorModel()
|
||||
* \since QGIS 3.40
|
||||
*/
|
||||
void setColorModel( Qgis::ColorModel colorModel );
|
||||
|
||||
/**
|
||||
* Returns project color model
|
||||
*
|
||||
* Used as default color model when selecting a color in the whole application.
|
||||
* Any color defined in a different color model than the returned will be converted to
|
||||
* this color model when exporting a layout
|
||||
*
|
||||
* defaults to Qgis::ColorModel::Rgb
|
||||
*
|
||||
* \see setColorModel()
|
||||
* \since QGIS 3.40
|
||||
*/
|
||||
Qgis::ColorModel colorModel() const;
|
||||
|
||||
/**
|
||||
* Set project current \a colorSpace. \a colorSpace must be a valid RGB or CMYK color space.
|
||||
* Color space ICC profile will be added as a project attached file.
|
||||
*
|
||||
* Project color space will be added to PDF layout export if defined (meaning different from
|
||||
* the default invalid QColorSpace).
|
||||
*
|
||||
* If a color model has already been set and it differs from \a colorSpace color model, project
|
||||
* color model is set to \a colorSpace one. \see setColorModel() colorModel()
|
||||
*
|
||||
* defaults to invalid color space
|
||||
*
|
||||
* \see colorSpace()
|
||||
* \since QGIS 3.40
|
||||
*/
|
||||
void setColorSpace( const QColorSpace &colorSpace );
|
||||
|
||||
/**
|
||||
* Returns current project color space.
|
||||
*
|
||||
* Project color space will be added to PDF layout export if defined (meaning different from
|
||||
* the default invalid QColorSpace).
|
||||
*
|
||||
* defaults to invalid color space
|
||||
*
|
||||
* \see setColorSpace()
|
||||
* \since QGIS 3.40
|
||||
*/
|
||||
QColorSpace colorSpace() const;
|
||||
|
||||
/**
|
||||
* Reads the settings's state from a DOM element.
|
||||
* \see writeXml()
|
||||
@ -283,10 +345,14 @@ class CORE_EXPORT QgsProjectStyleSettings : public QObject
|
||||
QList< QPointer< QgsStyle > > mStyles;
|
||||
|
||||
QgsCombinedStyleModel *mCombinedStyleModel = nullptr;
|
||||
Qgis::ColorModel mColorModel = Qgis::ColorModel::Rgb;
|
||||
QColorSpace mColorSpace;
|
||||
QString mIccProfileFilePath;
|
||||
|
||||
void loadStyleAtPath( const QString &path );
|
||||
void clearStyles();
|
||||
|
||||
friend class TestQgsProjectProperties;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -5130,6 +5130,18 @@ class CORE_EXPORT Qgis
|
||||
};
|
||||
Q_ENUM( SensorThingsEntity )
|
||||
|
||||
/**
|
||||
* Color model types
|
||||
*
|
||||
* \since QGIS 3.40
|
||||
*/
|
||||
enum class ColorModel : int
|
||||
{
|
||||
Rgb,
|
||||
Cmyk
|
||||
};
|
||||
Q_ENUM( ColorModel )
|
||||
|
||||
/**
|
||||
* Identify search radius in mm
|
||||
*/
|
||||
|
||||
@ -18,11 +18,12 @@
|
||||
#include "qgscolorutils.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QColorSpace>
|
||||
#include <QDomDocument>
|
||||
#include <QFile>
|
||||
#include <QRegularExpression>
|
||||
#include <QRegularExpressionMatch>
|
||||
|
||||
|
||||
void QgsColorUtils::writeXml( const QColor &color, const QString &identifier, QDomDocument &document, QDomElement &element, const QgsReadWriteContext & )
|
||||
{
|
||||
{
|
||||
@ -353,3 +354,57 @@ QColor QgsColorUtils::colorFromString( const QString &string )
|
||||
}
|
||||
return QColor();
|
||||
}
|
||||
|
||||
QColorSpace QgsColorUtils::iccProfile( const QString &iccProfileFilePath, QString &errorMsg )
|
||||
{
|
||||
if ( iccProfileFilePath.isEmpty() )
|
||||
return QColorSpace();
|
||||
|
||||
QFile file( iccProfileFilePath );
|
||||
if ( !file.open( QIODevice::ReadOnly ) )
|
||||
{
|
||||
errorMsg = QObject::tr( "Failed to open ICC Profile: %1" ).arg( iccProfileFilePath );
|
||||
return QColorSpace();
|
||||
}
|
||||
|
||||
QColorSpace colorSpace = QColorSpace::fromIccProfile( file.readAll() );
|
||||
if ( !colorSpace.isValid() )
|
||||
{
|
||||
errorMsg = QObject::tr( "Invalid ICC Profile: %1" ).arg( iccProfileFilePath );
|
||||
return colorSpace;
|
||||
}
|
||||
|
||||
return colorSpace;
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||
|
||||
Qgis::ColorModel QgsColorUtils::toColorModel( QColorSpace::ColorModel colorModel, bool *ok )
|
||||
{
|
||||
bool lok;
|
||||
Qgis::ColorModel res;
|
||||
switch ( colorModel )
|
||||
{
|
||||
case QColorSpace::ColorModel::Cmyk:
|
||||
lok = true;
|
||||
res = Qgis::ColorModel::Cmyk;
|
||||
break;
|
||||
|
||||
case QColorSpace::ColorModel::Rgb:
|
||||
lok = true;
|
||||
res = Qgis::ColorModel::Rgb;
|
||||
break;
|
||||
|
||||
case QColorSpace::ColorModel::Undefined:
|
||||
case QColorSpace::ColorModel::Gray: // not supported
|
||||
lok = false;
|
||||
res = Qgis::ColorModel::Rgb;
|
||||
}
|
||||
|
||||
if ( ok )
|
||||
*ok = lok;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QDomElement>
|
||||
#include <QColorSpace>
|
||||
|
||||
class QgsReadWriteContext;
|
||||
|
||||
@ -94,6 +95,23 @@ class CORE_EXPORT QgsColorUtils
|
||||
*/
|
||||
static QColor colorFromString( const QString &string );
|
||||
|
||||
/**
|
||||
* Load \a iccProfileFilePath and returns associated color space.
|
||||
* If an error occurred, an invalid color space is returned and \a errorMsg is updated with error
|
||||
* message
|
||||
*/
|
||||
static QColorSpace iccProfile( const QString &iccProfileFilePath, QString &errorMsg );
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||
|
||||
/**
|
||||
* Convert and returns Qt \a colorModel to Qgis::ColorModel. \a ok is set to true if \a colorModel
|
||||
* is a valid Qgis::ColorModel.
|
||||
*/
|
||||
static Qgis::ColorModel toColorModel( QColorSpace::ColorModel colorModel, bool *ok = nullptr ) SIP_SKIP;
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSCOLORUTILS_H
|
||||
|
||||
@ -11,12 +11,14 @@ __copyright__ = 'Copyright 2019, The QGIS Project'
|
||||
|
||||
from qgis.PyQt.QtCore import (
|
||||
QCoreApplication,
|
||||
QDir,
|
||||
QEvent,
|
||||
QModelIndex,
|
||||
Qt,
|
||||
QTemporaryDir,
|
||||
QTemporaryFile
|
||||
)
|
||||
from qgis.PyQt.QtGui import QColor, QFont
|
||||
from qgis.PyQt.QtGui import QColor, QColorSpace, QFont
|
||||
from qgis.PyQt.QtTest import QSignalSpy
|
||||
from qgis.PyQt.QtXml import QDomDocument
|
||||
from qgis.core import (
|
||||
@ -32,7 +34,9 @@ from qgis.core import (
|
||||
QgsTextFormat,
|
||||
QgsWkbTypes,
|
||||
)
|
||||
|
||||
import unittest
|
||||
import os
|
||||
from qgis.testing import start_app, QgisTestCase
|
||||
|
||||
from utilities import unitTestDataPath
|
||||
@ -409,7 +413,8 @@ class TestQgsProjectViewSettings(QgisTestCase):
|
||||
QgsStyle.defaultStyle())
|
||||
|
||||
def testReadWrite(self):
|
||||
p = QgsProjectStyleSettings()
|
||||
project = QgsProject()
|
||||
p = QgsProjectStyleSettings(project)
|
||||
|
||||
line = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.LineGeometry)
|
||||
p.setDefaultSymbol(Qgis.SymbolType.Line, line)
|
||||
@ -443,6 +448,60 @@ class TestQgsProjectViewSettings(QgisTestCase):
|
||||
self.assertEqual(p2.styleDatabasePaths(),
|
||||
[unitTestDataPath() + '/style1.db', unitTestDataPath() + '/style2.db'])
|
||||
|
||||
def testColorSettings(self):
|
||||
"""
|
||||
Test ICC profile attachment
|
||||
"""
|
||||
project = QgsProject()
|
||||
settings = project.styleSettings()
|
||||
|
||||
self.assertEqual(settings.colorModel(), Qgis.ColorModel.Rgb)
|
||||
self.assertFalse(settings.colorSpace().isValid())
|
||||
|
||||
# set Cmyk color model and color space
|
||||
|
||||
settings.setColorModel(Qgis.ColorModel.Cmyk)
|
||||
self.assertEqual(settings.colorModel(), Qgis.ColorModel.Cmyk)
|
||||
|
||||
with open(os.path.join(TEST_DATA_DIR, "sRGB2014.icc"), mode='rb') as f:
|
||||
colorSpace = QColorSpace.fromIccProfile(f.read())
|
||||
|
||||
self.assertTrue(colorSpace.isValid())
|
||||
|
||||
settings.setColorSpace(colorSpace)
|
||||
self.assertTrue(settings.colorSpace().isValid())
|
||||
self.assertEqual(settings.colorSpace().primaries(), QColorSpace.Primaries.SRgb)
|
||||
self.assertEqual(len(project.attachedFiles()), 2)
|
||||
|
||||
# save and restore
|
||||
projectFile = QTemporaryFile(QDir.temp().absoluteFilePath("testCmykSettings.qgz"))
|
||||
projectFile.open()
|
||||
self.assertTrue(project.write(projectFile.fileName()))
|
||||
|
||||
project = QgsProject()
|
||||
self.assertTrue(project.read(projectFile.fileName()))
|
||||
settings = project.styleSettings()
|
||||
self.assertEqual(settings.colorModel(), Qgis.ColorModel.Cmyk)
|
||||
self.assertTrue(settings.colorSpace().isValid())
|
||||
self.assertEqual(settings.colorSpace().primaries(), QColorSpace.Primaries.SRgb)
|
||||
self.assertEqual(len(project.attachedFiles()), 2)
|
||||
|
||||
# clear color space
|
||||
settings.setColorSpace(QColorSpace())
|
||||
self.assertFalse(settings.colorSpace().isValid())
|
||||
self.assertEqual(len(project.attachedFiles()), 1)
|
||||
|
||||
# save and restore cleared
|
||||
projectFile = QTemporaryFile(QDir.temp().absoluteFilePath("testCmykSettingsCleared.qgz"))
|
||||
projectFile.open()
|
||||
self.assertTrue(project.write(projectFile.fileName()))
|
||||
|
||||
project = QgsProject()
|
||||
self.assertTrue(project.read(projectFile.fileName()))
|
||||
settings = project.styleSettings()
|
||||
self.assertFalse(settings.colorSpace().isValid())
|
||||
self.assertEqual(len(project.attachedFiles()), 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
BIN
tests/testdata/sRGB2014.icc
vendored
Normal file
BIN
tests/testdata/sRGB2014.icc
vendored
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user