Tk_PhotoPutBlock无法正确渲染SVG文件的技术问题
SVG转Tk Photo对象颜色不一致问题
我尝试用C语言结合Tk API,基于resvg库实现SVG转Tk Photo对象并在Tk Frame中显示的功能。
使用的SVG内容如下:
<svg id="svg1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <circle r="32" cx="35" cy="65" fill="#F00" opacity="0.5"/> <circle r="32" cx="65" cy="65" fill="#0F0" opacity="0.5"/> <circle r="32" cx="50" cy="35" fill="#00F" opacity="0.5"/> </svg>
对应的C代码实现:
Tk_PhotoHandle source; unsigned char *imgData; // PhotoObj : set photo [image create photo]; # tcl code // FileObj : file.svg source = Tk_FindPhoto(interp, Tcl_GetString(PhotoObj)); if (source == NULL) { Tcl_SetResult(interp, "photo not found", TCL_STATIC); return TCL_ERROR; } char *sp = Tcl_GetString(FileObj); resvg_init_log; resvg_options *opt = resvg_options_create(); resvg_options_load_system_fonts(opt); resvg_render_tree *tree; int err = resvg_parse_tree_from_file(sp, opt, &tree); resvg_options_destroy(opt); if (err != RESVG_OK) { printf("Error id: %i\n", err); return TCL_ERROR; } resvg_size size = resvg_get_image_size(tree); int width = (int)size.width; int height = (int)size.height; imgData = (unsigned char *)Tcl_Alloc(width*height*4); if (imgData == NULL) { Tcl_SetResult(interp, "cannot alloc image buffer", TCL_STATIC); return TCL_ERROR; } resvg_render(tree, resvg_transform_identity(), width, height, imgData); Tk_PhotoImageBlock block; Tk_PhotoGetImage(source, &block); block.pixelPtr = imgData; block.width = width; block.height = height; block.pitch = width * 4; block.pixelSize = 4; block.offset[0] = 0; block.offset[1] = 1; block.offset[2] = 2; block.offset[3] = 3; if (Tk_PhotoSetSize(interp, source, width, height) != TCL_OK) { return TCL_ERROR; } Tk_PhotoPutBlock(interp, source, &block, 0, 0, width, height, TK_PHOTO_COMPOSITE_SET); resvg_tree_destroy(tree); return TCL_OK;

如图所示,左侧原SVG的颜色与右侧Tk中显示的图像颜色不一致。我怀疑问题出在imgData的数据格式上,原resvg示例中针对cairo表面做了数据转换处理,但我对图像格式转换了解有限,不知道Tk端需要如何调整数据才能匹配正确的颜色。
内容的提问来源于stack exchange,提问作者n.robert
相关产品推荐
相关产品推荐

