MIT License

技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

ComfyUI-PixelArt-Detector 技术分析

项目背景与痛点

在数字时代,像素艺术受到了越来越多艺术家和设计师的青睐。然而,由于影像技术的发展,旧有的像素艺术作品在高清化的趋势中暴露出很多问题。例如,放大过程中图像会失真,颜色过渡不自然等。针对这种痛点,dimtoneff/ComfyUI-PixelArt-Detector 这个项目提供了一套高效率的解决方案,利用 SDXL(Super Resolution XL)等技术,对像素艺术图像进行生成、降尺度和颜色重新调和,使旧有的作品焕发出新的生命力。

核心技术揭秘

该项目的架构设计优良,核心技术栈包括 Python、PyTorch 等主流工具和框架,通过 SDXL 技术,能有效提升图像的分辨率,同时保持原有艺术风格。项目中用到的关键节点包括:

  • Astropulse/Pixeldetector Node:用于识别像素艺术图像的具体区块,这一步是关键,它直接决定了后续处理的质量。
  • Palette Loader from Image:通过智能算法从图像中提取调色盘。试想一下,当你需要将一幅复杂的像素艺术图像转换为具有特定风格的新图像时,这个功能的重要性不言而喻。
  • Grid View for palettes:给用户提供一个直观的调色板界面,对颜色进行管理和调整。

以下是项目数据流的概览:

graph TD A[加载像素艺术图像] --> B[调用 Pixeldetector Node] B --> C{"是否检测到像素区块?"} C -->|"是"| D[调用 Palette Loader from Image] C -->|"否"| E[返回错误提示] D --> F[显示调色板] F --> G[用户调整颜色] G --> H[应用新颜色] H --> I[降尺度处理] I --> J[保存结果] J --> K[返回处理后的图像]

此外,项目设计中还大量应用了模块化设计思想,使得每一部分功能独立且易于维护。例如,调整颜色的过程和最终生成图像的步骤通过不同节点实现,结构清晰,层次分明。

功能亮点与差异

相较于其他类似的像素艺术处理工具,ComfyUI-PixelArt-Detector 在用户交互和灵活度上有其独到之处。通过丰富的节点组合,用户可以自由创建出所需的独特效果。在处理色调时,用户可以直观地看到不同颜色的情景模拟并进行修改,这在同类工具中是极为少见的。另外,无论是从性能还是新鲜感来看,该项目都展示出了明显的优势。

应用场景与落地建议

虽然此项目在宏大的创意自由度方面表现出色,但在生产环境中使用还需谨慎。处理高分辨率图像时,用户的机器配置必须满足需求,特别是显存和处理器能力。建议用户在正式使用前,可以通过模拟器或测试服务对图像处理的初步效果进行预览,以便及早调节系统资源。

该工具特别适用于需要对历史像素艺术作品进行复原或再创造的项目,例如独立游戏开发、复古艺术修复等。同时也为开发者的创意增加了更多维度,提升了作品的艺术水平。

综合评价

ComfyUI-PixelArt-Detector 拥有高效、直观的用户体验和灵活的开发架构,是像素艺术处理领域的有力选手,对于从事像素艺术创作和修复工作的开发者而言提供了极大的便利。但是,其对机器性能的要求较高,在使用时需要考虑硬件支持的问题。总体来说,这是一款值得开发者深入研究和使用的优秀工具。

关于

GitHub 原始描述(英文)

Generate, downscale, change palletes and restore pixel art images with SDXL. Nodes for Astropulse/pixeldetector, Palette Loader from Image, Grid view for palettes etc.

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

简要分析

热度分
516
价值分
281
活跃状态
活跃

语言占比

JavaScript
Python

README

ComfyUI PixelArt Detector v1.7.3

Generate, downscale, change palletes and restore pixel art images with SDXL.

Save a picture as Webp (+optional JPEG) file in Comfy + Workflow loading.

Update 1.7.3:

  • Added install for prebuilt pyclustering library

Update 1.7.2:

  • Updated all the workflows
  • Added a lot of new palettes

Update 1.7.0:

All changes maintain backward compatibility while providing users with more control over image resizing behavior:

  • Added a wrapper for the Astropulse’s algo making sure no distortions happen with uncommon ARs by enforcing a single uniform factor, the geometry is preserved and no axis is stretched differently
  • Added a reusable resize_image function in pixelUtils.py that supports three resize modes:
    • “contain”: Maintains aspect ratio with shrinking and fits within specified dimensions (default)
    • “fit”: Maintains aspect ratio but crops to fill entire area
    • “stretch”: Stretches to exact dimensions, may distort image in uncommon aspect ratios
  • Updated PixelArtDetectorConverter, PixelArtDetectorConverter and PixelArtDetectorSave classes to use the new resize_image function

Update 1.6.1:

  • Node Frontend Improvements:
    • PixelArtLoadPalettes: now has a preview of the palettes. Changing the palette triggers a preview of the unique palette colors in the node without a workflow run
    • PixelArtLoadPalettes: implemented dynamic widget show/hide logic for the grid settings.

Update 1.6.0:

  • Refactored PixelArtDetectorConverter node:
    • Separated quantization methods from reducing methods.
    • Fixed dithering.
    • Added more dynamic widget show/hide logic.
  • Workflow Updates:
    • Updated and moved all workflows to example_workflows directory.
    • Added images for workflows.
    • Added a new workflow for the new PixelArtPaletteGenerator node
  • Compatibility & Dependencies:
    • Compatible with ComfyUI v0.3.49.
    • Bumped some requirements versions and fixed numpy versioning error.
    • Adjusted Javascript files according to the new ComfyUI frontend.
  • New Node:
    • Introduced PixelArtPaletteGenerator for generating palettes from images Thanx @za-wa-n-go

Update 1.5.2:

  • Fixed the compatibility with Python <3.10
  • Fixed a scipy ‘signal’ error

Update 1.5.1: @tsone added a new dithering node: PixelArtAddDitherPattern

  • with prepared patterns
  • with custom patterns from a mask
  • also added a b&w palette

Update 1.5: Maintenance & Dithering + bugfixes

  • added dithering
  • made the node compatible with Pillow < 10 & Pillow > 10
  • fixed an issue where changing the fontSize in grids did not work
  • fixed an issue with Pillow library and ImageDraw.textsize not available in Pillow>= 10.0
  • fixed an issue with text too long in Grids
  • fixed an issue with the NP.quantize method

Dithering examples:

Update 1.4: Added a check and installation for the opencv (cv2) library used with the nodes. This should fix the reported issues people were having.

Update 1.3: Updated all 4 nodes. Please, pull this and exchange all your PixelArt nodes in your workflow. Mind the settings.

  • added OpenCV.kmeans algo to reduce colors in an image. Working only when reducing colors.
  • added “clean up” pixels function which uses Image.quantize to iterate over the image and eliminate colors based on given threshold. Runs after optional reducing of colors step
  • added different algos to reduce image with Image.quantize method (default one). MEDIANCUT, MAXCOVERAGE etc. MAXCOVERAGE seems to produce cleaner pixel art. FASTOCTREE is fast and bad
  • updated choices to BOOLEANs and toggles
  • added the “NP.quantize” method using fast numpy arrays to reduce and exchange palettes
  • moved out the grid settings from the Palette Converter to the Palette Loader
  • and many other small additions

Update 1.2: PixelArtDetectorConverter will upscale the image BEFORE the pixelization/quantization process if the input image is smaller than the resize sizes. If bigger, it will downscale after quantization.

Update 1.1: changed the default workflow.json to use the default “Save Image” node. workflow_webp.json will be using the webp node.

[!IMPORTANT] If you have an older version of the nodes, delete the node and add it again. Location of the nodes: “Image/PixelArt”. I’ve added some example workflow in the workflow.json. The example images might have outdated workflows with older node versions embedded inside.

Description:

Pixel Art manipulation code based on: https://github.com/Astropulse/pixeldetector

This adds 6 custom nodes:

  • PixelArt Detector (+Save) - this node is All in One reduce palette, resize, saving image node
  • PixelArt Detector (Image->) - this node will downscale and reduce the palette and forward the image to another node
  • PixelArt Palette Converter - this node will change the palette of your input. There are a couple of embedded palettes. Use the Palette Loader for more
  • PixelArt Palette Loader - this node comes with a lot of custom palettes which can be an input to the PixelArt Palette Converter “paletteList” input. Optional GRIDS preview of all palettes
  • PixelArt Palette Generator - this node generates a color palette from an input image.
  • PixelArtAddDitherPattern - this node adds a dither pattern to the image.

The plugin also adds a script to Comfy to drag and drop generated webp|jpeg files into the UI to load the workflows.

The nodes are able to manipulate the pixel art image in ways that it should look pixel perfect (downscales, changes palette, upscales etc.).

Important 重要

You can disable the embedded resize function in the nodes by setting W & H to 0.

Installation:

To use these nodes, simply open a terminal in ComfyUI/custom_nodes/ and run:

git clone https://github.com/dimtoneff/ComfyUI-PixelArt-Detector

I am using a “Save_as_webp” node to save my output images (check the workflow_webp.json). You can find my customization in the following repo (part of the workflow).

Just execute this command in ComfyUI/custom_nodes/ too.

git clone https://github.com/dimtoneff/ComfyUI-Saveaswebp

Original “Save_as_webp” node repo: https://github.com/Kaharos94/ComfyUI-Saveaswebp.

If you don’t want to use “Save_as_webp” nodes, just delete them from my workflow in workflow_webp.json and add the default “Save Image” node to save as PNG (or use the default workflow.json)

Restart ComfyUI afterwards.

New node: “PixelArt Palette Generator”

This node can generate a color palette from a given image. You can specify the number of colors and the layout of the generated palette image.

Extra info about the “PixelArt Palette Generator” Node:

  • colors: The number of colors to be generated in the palette.
  • mode: The layout of the generated palette image.
    • Chart: A grid layout for the colors.
    • back_to_back: A horizontal strip of colors.

The node outputs an image of the palette and a list of colors that can be used with the PixelArt Palette Converter node.

Usage

Use LoRa: https://civitai.com/models/120096/pixel-art-xl

Drag the workflow.json file in your ComfyUI

Set the resize inputs to 0 to disable upscaling in the “Save” node.

Reduce palettes or completely exchange palettes on your images.

text2image

Positive prompt: pixelart, {your scene}, pixel-art. low-res, blocky, pixel art style, 8-bit graphics, sharp details, less colors, early computer game art

Negative prompt: sloppy, messy, blurry, noisy, highly detailed, ultra textured, photo, realistic, high-resolution, photo-realistic

image2image

on a pixel drawing converting to a pixel asset for finetuning:

Input:

Output:

Feel free to experiment! Free web tool for pixel art: https://www.pixilart.com/draw

Other image2image examples: Discussion in the issues

Extra info about the “PixelArt Detector (+Save)” Node:

There is a compression slider and a lossy/lossless option for webp. The compression slider is a bit misleading.

In lossless mode, it only affects the “effort” taken to compress where 100 is the smallest possible size and 1 is the biggest possible size, it’s a tradeoff for saving speed.

In lossy mode, that’s the other way around, where 100 is the biggest possible size with the least compression and 1 is the smallest possible size with maximum compression.

There is an option to save a JPEG alongside the webp file.

Extra info about the “PixelArt Palette Converter” Node:

  • palette: a couple of retro palettes used if the paletteList input is not used
  • pixelize: here we have different algos to reduce colors & replace palettes
    • Image.quantize: uses PIL Image functions to reduce colors & replace palettes. You can change the reduce algo with “image_quantize_reduce_method”
    • Grid.pixelate: a custom algo to exchange palettes. Slow when grid_pixelate_grid_scan_size is 1
    • NP.quantize: a custom algo to exchange paletes. Using fast numpy arrays. Slower than Image.quantize
  • grid_pixelate_grid_scan_size option is for the pixelize grid.Pixelate option. Size of 1 is pixel by pixel. Very slow. Increasing the size improves speed but kills quality. Experiment or not use that option.
  • resize_w & resize_h: it will downscale or upscale the end result to these sizes
  • reduce_colors_before_palette_swap: it’s going to reduce colors with either Image.quantize or one of the other algos.
  • reduce_colors_method: The algorithm to use for color reduction.
    • Image.quantize: uses PIL Image functions to reduce colors. Fast.
    • OpenCV.kmeans.reduce: using the OpenCV library to reduce colors. It is slow but good when attempts & iterations are higher. You can change the way it picks colors with the option “opencv_kmeans_centers”.
    • Pycluster.kmeans.reduce: using the Pyclustering library to reduce colors with the K-Means algorithm.
    • Pycluster.kmedians.reduce: using the Pyclustering library to reduce colors with the K-Medians algorithm.
  • reduce_colors_max_colors: the colors count to reduce the image to
  • apply_pixeldetector_max_colors: use the Astropulse’s PixelDetector to grab the max dominant colors.
  • image_quantize_reduce_method: the method used from Image.quantize pixelize option to reduce colors. MAXCOVERAGE seems good for pixel art. But try the rest too.
  • opencv_kmeans_centers: a flag how to pick the labels/colors. RANDOM is… random. Interesting results. Increasing attempts makes it slower but picks the best colors.
    • KMEANS_RANDOM_CENTERS: it always starts with a random set of initial samples, and tries to converge from there depending upon TermCriteria. Fast but doesn’t guarantee same labels for the exact same image. Needs more “attempts” to find the “best” labels
    • KMEANS_PP_CENTERS: it first iterates the whole image to determine the probable centers and then starts to converge. Slow but will yield optimum and consistent results for same input image.
  • opencv_kmeans_attempts: how many times to attempt finding the best colors to reduce the image to
  • opencv_criteria_max_iterations: how many iterations per attempt
  • pycluster_kmeans_metrics: The metric to use for Pycluster algorithms.
  • cleanup_colors: given a threshold, iterate over the image and eliminate less used colors. May be combined with the reduce_colos_before_palette_swap option for optimal clean up. Or optimal break of the image :)
  • cleanup_pixels_threshold: the threshold for the cleanup function. Good values: 0.01-0.05. If it eliminates too much, lower the value. LOWER VALUE = MORE COLORS
  • dither: apply dithering for more “retro” look

Extra info about the “PixelArt Palette Converter” and “PixelArt Palette Loader” Nodes:

Included palettes from: https://lospec.com/palette-list

Important 重要

If you like some palette, download the 1px one and add it to the “ComfyUI-PixelArt-Detector\palettes\1x” directory.

GRIDS

  • Connect the PixelArt Palette Loader to the PixelArt Palette Converter or use the “grid.json” file and drag&drop into ComfyUI
  • enable the render_all_palettes_in_grid
  • use the default “Preview Image” node to preview the grids (preferably)
  • play with the settings

Grids

Community examples:

Screenshots

Nodes:

Example

Workflow view:

Example

Here are some palette change examples:

Example Example

Example Example

Example Example

Example Example

Example Example

Examples

Normal image:

Example Example

Reduced palette:

Example Example

Example Example

Upscaled:

Example

Example

Credits

Big thanks to https://github.com/Astropulse/pixeldetector for the main code.

Big thanks to https://github.com/Kaharos94/ComfyUI-Saveaswebp for the webp saving code.

Big thanks to https://github.com/paultron for numpy-ifying the downscale calculation and making it tons faster.

Big thanks to https://lospec.com/palette-list and the creators of the awesome palettes.

评论

暂无评论