我在资源中加载了一个svg,但它是黑色的。如何将颜色更改为白色?
答案 0 :(得分:7)
这是你在Qt中可以做到的,不要忘记将xml和svg模块添加到你的qt项目(* .pro文件)。此代码段通过修改任何“path”元素的“fill”属性来更改颜色,但您可以使用它来修改任何元素的任何属性。
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);
}
}
答案 1 :(得分:5)
由于SVG格式是基于XML的,而XML只是ASCII文本...您可以将SVG资源加载到QString中,调用QString :: replace(“\”#000000 \“”,“\”# ffffff \“”),然后将修改后的QString传递给你的QSVGRenderer。
答案 2 :(得分:2)
只要你在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。
希望有所帮助。
答案 3 :(得分:0)
如果白色是您需要的唯一颜色,那么一个简单的解决方案就是使用图像编辑器(例如Inkscape)更改原始SVG图像的颜色。当然,如果您需要使用具有许多不同颜色的图像,那么这不是一个合理的解决方案。
答案 4 :(得分:0)
您可以使用ColorOverlay,如该问题末尾所述:
Qt QML LevelAdjust shows strange edge effects when applied to svg source
它不会改变SVG的大小,但会创建一个彩色图层,该图层的形状与您的图形相同(假设图形的背景是透明的)。
答案 5 :(得分:0)
如果您的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,但是鉴于几乎所有提供图标的网站都使用黑色,因此非常简洁。
答案 6 :(得分:0)
#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;
}
答案 7 :(得分:0)
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)