リソースにsvgがロードされていますが、黒です。色を白に変更するにはどうすればよいですか?
8 に答える
これがQtでそれを行う方法です。xmlおよびsvgモジュールをqtプロジェクト(* .proファイル)に追加することを忘れないでください。このコードスニペットは、任意の「パス」要素の「塗りつぶし」属性を変更することで色を変更しますが、これを使用して任意の要素の任意の属性を変更できます。
void SetAttrRecur(QDomElement &elem, QString strtagname, QString strattr, QString strattrval);
void ChangeSVGColor()
{
// open svg resource load contents to qbytearray
QFile file("myfile.svg");
file.open(QIODevice::ReadOnly);
QByteArray baData = file.readAll();
// load svg contents to xml document and edit contents
QDomDocument doc;
doc.setContent(baData);
// recurivelly change color
SetAttrRecur(doc.documentElement(), "path", "fill", "white");
// create svg renderer with edited contents
QSvgRenderer svgRenderer(doc.toByteArray());
// create pixmap target (could be a QImage)
QPixmap pix(svgRenderer.defaultSize());
pix.fill(Qt::transparent);
// create painter to act over pixmap
QPainter pixPainter(&pix);
// use renderer to render over painter which paints on pixmap
svgRenderer.render(&pixPainter);
QIcon myicon(pix);
// Use icon ....
}
void SetAttrRecur(QDomElement &elem, QString strtagname, QString strattr, QString strattrval)
{
// if it has the tagname then overwritte desired attribute
if (elem.tagName().compare(strtagname) == 0)
{
elem.setAttribute(strattr, strattrval);
}
// loop all children
for (int i = 0; i < elem.childNodes().count(); i++)
{
if (!elem.childNodes().at(i).isElement())
{
continue;
}
SetAttrRecur(elem.childNodes().at(i).toElement(), strtagname, strattr, strattrval);
}
}
SVG形式はXMLベースであり、XMLは単なるASCIIテキストであるため、SVGリソースをQStringにロードして、QString :: replace( "\"#000000 \ ""、 "\"#ffffff\"を呼び出すことができます。 ")次に、変更したQStringをQSVGRendererに渡します。
SVGが黒の場合、それを行う非常に簡単な方法があります:QGraphicsEffect
#include <QGraphicsItem>
#include <QGraphicsColorizeEffect>
QGraphicsItem *item;
QGraphicsColorizeEffect *effect;
item = new QGraphicsItem;
effect = new QGraphicsColorizeEffect;
effect->setColor(Qt::white);
effect->setStrength(1);
item->setGraphicsEffect(effect)
これは白いSVGでは機能しませんが、アイコンを提供するほとんどすべてのWebサイトが黒で機能することを考えると、これはかなりきれいです。
Macで必要ない限り、これは機能するはずです。
http://doc-snapshot.qt-project.org/4.8/qwidget.html#setGraphicsEffect
http://doc-snapshot.qt-project.org/4.8/qgraphicscolorizeeffect.html
編集:または、Macをサポートする必要がある場合は、QGraphicsView内でsvgレンダリングとエフェクトを実行します。
http://doc-snapshot.qt-project.org/4.8/qgraphicsitem.html#setGraphicsEffect
色付け効果を設定して白に着色し、svgWidgetに設定します。
お役に立てば幸いです。
pyqt5のソリューション。あなたはそれをc++に簡単に変換することができます
def QIcon_from_svg(svg_filepath, color='black'):
img = QPixmap(svg_filepath)
qp = QPainter(img)
qp.setCompositionMode(QPainter.CompositionMode_SourceIn)
qp.fillRect( img.rect(), QColor(color) )
qp.end()
return QIcon(img)
この質問の最後で説明されているように、ColorOverlayを使用できます。
Qt QML LevelAdjustは、svgソースに適用されると奇妙なエッジ効果を示します
言うまでもなくSVGは変更されませんが、描画と同じ形状の色付きのレイヤーが作成されます(描画の背景が透明であると想定)。
#ifndef SVG_ITEM_H
#define SVG_ITEM_H
#include <QObject>
#include <QPen>
#include <QQuickItem>
#include <QQuickPaintedItem>
#include <QSvgRenderer>
class SVG_Item : public QQuickPaintedItem
{
Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
Q_PROPERTY(QPen stroke READ stroke WRITE setStroke NOTIFY strokeChanged)
Q_PROPERTY(bool debuging READ debuging WRITE setdebuging)
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged)
Q_OBJECT
public:
explicit SVG_Item(QQuickItem *parent = nullptr);
void paint(QPainter *painter) Q_DECL_OVERRIDE;
QString source() const;
QColor color() const;
QPen stroke() const;
bool debuging() const;
QColor backgroundColor() const;
signals:
void sourceChanged(QString source);
void colorChanged(QColor color);
void strokeChanged(QPen stroke);
void backgroundColorChanged(QColor backgroundColor);
public slots:
void setSource(QString source);
void setColor(QColor color);
void setStroke(QPen stroke);
void setdebuging(bool debuging);
void setBackgroundColor(QColor backgroundColor);
private:
QString m_source;
QColor m_color;
QPen m_stroke;
QString svgContent;
QSvgRenderer *renderer;
bool changed;
bool m_debuging;
QColor m_backgroundColor;
QColor m_test;
};
#endif // SVG_ITEM_H
#include "svg_item.h"
#include <QSvgRenderer>
#include <QDebug>
#include <QPainter>
#include <QSvgGenerator>
SVG_Item::SVG_Item(QQuickItem *parent) : QQuickPaintedItem(parent)
{
changed = false;
renderer = NULL;
m_debuging = false;
m_backgroundColor = Qt::transparent;
}
void SVG_Item::paint(QPainter *painter)
{
painter->fillRect(0,0,this->width(),this->height(),m_backgroundColor);
if(m_source != "")
{
if(changed)
{
if(renderer != NULL)
{
renderer->deleteLater();
}
renderer = new QSvgRenderer(svgContent.toLocal8Bit());
}
if(renderer != NULL)
renderer->render(painter);
}
}
void SVG_Item::setSource(QString source)
{
if(source.startsWith("qrc"))
source = source.remove(0,3);
if (m_source == source)
return;
QFile readFile(source);
if(!readFile.exists())
{
qWarning("file not found");
}
readFile.open(QFile::ReadOnly);
svgContent = readFile.readAll();
setColor(color());
//readData.replace()
m_source = source;
emit sourceChanged(m_source);
}
void SVG_Item::setColor(QColor color)
{
changed = true;
QString fillStr = "fill:%1";
fillStr = fillStr.arg(color.name());
svgContent = svgContent.replace(QRegExp("fill:[# 0-9 a b c d e f A B C D E F]+"), fillStr);
if(!svgContent.contains(QRegExp("fill:[# 0-9 a b c d e f A B C D E F]+")))
{
QString style = "<path \n style=\"fill:%1;fill-opacity:1\"";
style = style.arg(color.name());
svgContent = svgContent.replace("<path",style);
style = "<rect \n style=\"fill:%1;fill-opacity:1\"";
style = style.arg(color.name());
svgContent = svgContent.replace("<rect",style);
style = "<circle \n style=\"fill:%1;fill-opacity:1\"";
style = style.arg(color.name());
svgContent = svgContent.replace("<circle",style);
style = "<ellipse \n style=\"fill:%1;fill-opacity:1\"";
style = style.arg(color.name());
svgContent = svgContent.replace("<ellipse",style);
style = "<polygon \n style=\"fill:%1;fill-opacity:1\"";
style = style.arg(color.name());
svgContent = svgContent.replace("<polygon",style);
}
//
this->update();
if (m_color == color)
return;
m_color = color;
emit colorChanged(m_color);
}
void SVG_Item::setStroke(QPen stroke)
{
changed = true;
if (m_stroke == stroke)
return;
m_stroke = stroke;
emit strokeChanged(m_stroke);
}
void SVG_Item::setdebuging(bool debuging)
{
m_debuging = debuging;
}
void SVG_Item::setBackgroundColor(QColor backgroundColor)
{
if (m_backgroundColor == backgroundColor)
return;
m_backgroundColor = backgroundColor;
emit backgroundColorChanged(m_backgroundColor);
}
QString SVG_Item::source() const
{
return m_source;
}
QColor SVG_Item::color() const
{
return m_color;
}
QPen SVG_Item::stroke() const
{
return m_stroke;
}
bool SVG_Item::debuging() const
{
return m_debuging;
}
QColor SVG_Item::backgroundColor() const
{
return m_backgroundColor;
}
必要な色が白だけの場合、簡単な解決策は、画像エディタ(Inkscapeなど)を使用して元のSVG画像の色を変更することです。もちろん、多くの異なる色の画像を使用する必要がある場合、それは合理的な解決策にはなりません。