C++ Cairo + RSVG - 绘图时设置 SVG 颜色
C++ Cairo + RSVG - Set SVG colour when drawing
我正在尝试将单色 SVG 绘制到 Cairo 表面上,但在我希望它为黑色的地方呈现为白色。 Cairo 表面是一个 8 位 alpha 表面 (CAIRO_FORMAT_A8),所以我只处理灰度。
我正在测试的图像如下:https://commons.wikimedia.org/wiki/File:Octicons-flame.svg
这是我用来呈现的代码:
//Display buffer and Canvas
int stride;
Byte *displayBuffer;
cairo_surface_t *surface;
stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, gulPanelW);
displayBuffer = malloc (stride * gulPanelH);
surface = cairo_image_surface_create_for_data (displayBuffer, CAIRO_FORMAT_A8, gulPanelW, gulPanelH, stride);
cairo_t *cr = cairo_create (surface);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
//Flame Surface and SVG Handle
RsvgHandle* flame_handle;
flame_handle = rsvg_handle_new_from_file("flame.svg", 0);
//Set canvas background to grey
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.5);
cairo_paint (cr);
//Add initial data and output
cairo_select_font_face (cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 48.0);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
cairo_move_to (cr, 700.0, 105.0);
cairo_rotate(cr, (M_PI/2.0));
cairo_show_text (cr, "Temperature");
cairo_rotate(cr, -(M_PI/2.0));
cairo_select_font_face (cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 200.0);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
cairo_move_to (cr, 540.0, 34.0);
cairo_rotate(cr, (M_PI/2.0));
cairo_show_text (cr, "19.4");
cairo_rotate(cr, -(M_PI/2.0));
cairo_translate (cr, 476.0, 200.0);
cairo_scale (cr, 0.07, 0.07);
cairo_rotate(cr, (M_PI/2.0));
rsvg_handle_render_cairo (flame_handle, cr);
cairo_rotate (cr, -(M_PI/2.0));
cairo_scale (cr, 1.0, 1.0);
cairo_surface_write_to_png (surface, "output.png");
这将输出以下内容:
Cairo Output
但是如您所见,火焰呈现为白色,而我希望它是黑色 - 或特定的 alpha 值。
任何帮助将不胜感激,我在开罗找不到太多关于 SVG 颜色的信息。
非常感谢。
cairo_mask
和 cairo_mask_surface
可以使用另一个表面的 alpha 通道作为绘图操作的遮罩。以下示例将此用于 "draw things" 和特定的 alpha 级别。
我还添加了必要的东西,使它成为一个独立的例子,并去掉了不必要的 cairo_image_surface_create_for_data
。
#include <cairo.h>
#include <librsvg/rsvg.h>
#include <math.h>
#define gulPanelW 800
#define gulPanelH 480
int main()
{
//Display buffer and Canvas
cairo_surface_t *surface;
surface = cairo_image_surface_create (CAIRO_FORMAT_A8, gulPanelW, gulPanelH);
cairo_t *cr = cairo_create (surface);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
//Flame Surface and SVG Handle
RsvgHandle* flame_handle;
flame_handle = rsvg_handle_new_from_file("flame.svg", 0);
//Set canvas background to grey
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.5);
cairo_paint (cr);
//Add initial data and output
cairo_select_font_face (cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 48.0);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
cairo_move_to (cr, 700.0, 105.0);
cairo_rotate(cr, (M_PI/2.0));
cairo_show_text (cr, "Temperature");
cairo_rotate(cr, -(M_PI/2.0));
cairo_select_font_face (cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 200.0);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
cairo_move_to (cr, 540.0, 34.0);
cairo_rotate(cr, (M_PI/2.0));
cairo_show_text (cr, "19.4");
cairo_rotate(cr, -(M_PI/2.0));
// Draw the flame icon to a temporary surface
cairo_save (cr);
cairo_translate (cr, 476.0, 200.0);
cairo_scale (cr, 0.07, 0.07);
cairo_rotate(cr, (M_PI/2.0));
cairo_push_group (cr);
rsvg_handle_render_cairo (flame_handle, cr);
cairo_pattern_t *p = cairo_pop_group (cr);
// Use the temporary surface as a mask for drawing this color
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
cairo_mask(cr, p);
cairo_restore (cr);
// Clean up
cairo_surface_write_to_png (surface, "output.png");
cairo_pattern_destroy (p);
cairo_destroy (cr);
cairo_surface_destroy (surface);
return 0;
}
我正在尝试将单色 SVG 绘制到 Cairo 表面上,但在我希望它为黑色的地方呈现为白色。 Cairo 表面是一个 8 位 alpha 表面 (CAIRO_FORMAT_A8),所以我只处理灰度。
我正在测试的图像如下:https://commons.wikimedia.org/wiki/File:Octicons-flame.svg
这是我用来呈现的代码:
//Display buffer and Canvas
int stride;
Byte *displayBuffer;
cairo_surface_t *surface;
stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, gulPanelW);
displayBuffer = malloc (stride * gulPanelH);
surface = cairo_image_surface_create_for_data (displayBuffer, CAIRO_FORMAT_A8, gulPanelW, gulPanelH, stride);
cairo_t *cr = cairo_create (surface);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
//Flame Surface and SVG Handle
RsvgHandle* flame_handle;
flame_handle = rsvg_handle_new_from_file("flame.svg", 0);
//Set canvas background to grey
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.5);
cairo_paint (cr);
//Add initial data and output
cairo_select_font_face (cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 48.0);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
cairo_move_to (cr, 700.0, 105.0);
cairo_rotate(cr, (M_PI/2.0));
cairo_show_text (cr, "Temperature");
cairo_rotate(cr, -(M_PI/2.0));
cairo_select_font_face (cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 200.0);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
cairo_move_to (cr, 540.0, 34.0);
cairo_rotate(cr, (M_PI/2.0));
cairo_show_text (cr, "19.4");
cairo_rotate(cr, -(M_PI/2.0));
cairo_translate (cr, 476.0, 200.0);
cairo_scale (cr, 0.07, 0.07);
cairo_rotate(cr, (M_PI/2.0));
rsvg_handle_render_cairo (flame_handle, cr);
cairo_rotate (cr, -(M_PI/2.0));
cairo_scale (cr, 1.0, 1.0);
cairo_surface_write_to_png (surface, "output.png");
这将输出以下内容:
Cairo Output
但是如您所见,火焰呈现为白色,而我希望它是黑色 - 或特定的 alpha 值。
任何帮助将不胜感激,我在开罗找不到太多关于 SVG 颜色的信息。
非常感谢。
cairo_mask
和 cairo_mask_surface
可以使用另一个表面的 alpha 通道作为绘图操作的遮罩。以下示例将此用于 "draw things" 和特定的 alpha 级别。
我还添加了必要的东西,使它成为一个独立的例子,并去掉了不必要的 cairo_image_surface_create_for_data
。
#include <cairo.h>
#include <librsvg/rsvg.h>
#include <math.h>
#define gulPanelW 800
#define gulPanelH 480
int main()
{
//Display buffer and Canvas
cairo_surface_t *surface;
surface = cairo_image_surface_create (CAIRO_FORMAT_A8, gulPanelW, gulPanelH);
cairo_t *cr = cairo_create (surface);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
//Flame Surface and SVG Handle
RsvgHandle* flame_handle;
flame_handle = rsvg_handle_new_from_file("flame.svg", 0);
//Set canvas background to grey
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.5);
cairo_paint (cr);
//Add initial data and output
cairo_select_font_face (cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 48.0);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
cairo_move_to (cr, 700.0, 105.0);
cairo_rotate(cr, (M_PI/2.0));
cairo_show_text (cr, "Temperature");
cairo_rotate(cr, -(M_PI/2.0));
cairo_select_font_face (cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 200.0);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
cairo_move_to (cr, 540.0, 34.0);
cairo_rotate(cr, (M_PI/2.0));
cairo_show_text (cr, "19.4");
cairo_rotate(cr, -(M_PI/2.0));
// Draw the flame icon to a temporary surface
cairo_save (cr);
cairo_translate (cr, 476.0, 200.0);
cairo_scale (cr, 0.07, 0.07);
cairo_rotate(cr, (M_PI/2.0));
cairo_push_group (cr);
rsvg_handle_render_cairo (flame_handle, cr);
cairo_pattern_t *p = cairo_pop_group (cr);
// Use the temporary surface as a mask for drawing this color
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
cairo_mask(cr, p);
cairo_restore (cr);
// Clean up
cairo_surface_write_to_png (surface, "output.png");
cairo_pattern_destroy (p);
cairo_destroy (cr);
cairo_surface_destroy (surface);
return 0;
}