render-publication-graphic
Acerca de
Esta habilidad genera gráficos 2D listos para publicación, optimizados tanto para medios impresos como digitales. Maneja requisitos técnicos como DPI, perfiles de color y tipografía, asegurando que las salidas cumplan con las especificaciones de los editores. Los desarrolladores pueden utilizarla para crear y exportar gráficos en múltiples formatos desde una única fuente, destinados a revistas, impresión o web.
Instalación rápida
Claude Code
Recomendadonpx skills add pjt222/agent-almanac -a claude-code/plugin add https://github.com/pjt222/agent-almanacgit clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/render-publication-graphicCopia y pega este comando en Claude Code para instalar esta habilidad
Documentación
Render Publication Graphic
Produce publication-ready graphics that meet technical requirements for academic journals, books, presentations, and web publication. Covers DPI requirements, color space management, typography best practices, file format selection, and metadata embedding.
Cuándo Usar
- Preparing figures for academic journal submission
- Creating graphics for print publications (books, magazines)
- Generating high-quality assets for presentations
- Exporting visualizations for web publication with proper optimization
- Ensuring graphics meet publisher technical specifications
- Archiving graphics with proper metadata
- Creating multi-format exports from single source
Entradas
| Input | Type | Description | Example |
|---|---|---|---|
| Source graphic | File/Data | Original visualization or artwork | SVG, R ggplot, Python matplotlib, Blender render |
| Publication target | Specification | Journal, web, print, presentation | Nature journal, IEEE paper, website |
| Technical requirements | Parameters | DPI, dimensions, color space, format | 300 DPI, 180mm width, CMYK, TIFF |
| Style guide | Document | Publisher typography and formatting rules | Font families, line widths, color palette |
| Metadata | Information | Title, author, date, copyright, description | Figure caption, license info |
Procedimiento
1. Determine Output Requirements
Identify technical specifications for target publication:
# Common publication requirements
academic_journal:
dpi: 300-600
format: TIFF, EPS, PDF
color_space: RGB or CMYK (check guidelines)
max_width: 180mm (single column) or 390mm (double column)
fonts: Embed or outline
resolution_minimums:
line_art: 1000 DPI
halftone: 300 DPI
combination: 600 DPI
web_publication:
dpi: 72-96 (retina: 144-192)
format: PNG, WebP, SVG
color_space: sRGB
max_file_size: 200KB-500KB
optimization: Compress, progressive loading
presentation:
dpi: 96-150
format: PNG, PDF, SVG
color_space: RGB
dimensions: 16:9 or 4:3 aspect ratio
contrast: High contrast for projectors
print_book:
dpi: 300-600
format: TIFF, PDF/X
color_space: CMYK
bleed: 3-5mm beyond trim
fonts: Embedded
Esperado: Clear understanding of target requirements En caso de fallo: Contact publisher for specific guidelines, use conservative defaults
2. Set Correct DPI for Raster Graphics
Configure resolution based on output medium:
from PIL import Image
def set_dpi_pillow(image_path, output_path, target_dpi=300):
"""Set DPI metadata for PNG/TIFF."""
img = Image.open(image_path)
# Save with DPI metadata
img.save(output_path, dpi=(target_dpi, target_dpi))
print(f"Saved with {target_dpi} DPI: {output_path}")
def calculate_dimensions(width_mm, height_mm, dpi=300):
"""Calculate pixel dimensions from physical size."""
# Convert mm to inches
width_inches = width_mm / 25.4
height_inches = height_mm / 25.4
# Calculate pixels
width_px = int(width_inches * dpi)
height_px = int(height_inches * dpi)
return width_px, height_px
# Example: 180mm wide figure at 300 DPI
width, height = calculate_dimensions(180, 120, dpi=300)
print(f"Required resolution: {width}x{height} pixels")
# Output: Required resolution: 2126x1417 pixels
# R ggplot2 export with proper DPI
library(ggplot2)
# Create plot
p <- ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
theme_minimal(base_size = 12)
# Save for publication (300 DPI)
ggsave(
filename = "figure1.png",
plot = p,
width = 180,
height = 120,
units = "mm",
dpi = 300
)
# Save as vector for flexibility
ggsave(
filename = "figure1.pdf",
plot = p,
width = 180,
height = 120,
units = "mm",
device = cairo_pdf # Better text rendering
)
Esperado: Graphics rendered at correct resolution for print quality En caso de fallo: Verify DPI metadata saved correctly, check file size appropriate
3. Configure Color Space
Set appropriate color profile:
from PIL import Image, ImageCms
def convert_to_cmyk(rgb_image_path, cmyk_output_path):
"""Convert RGB to CMYK for print."""
img = Image.open(rgb_image_path)
if img.mode != 'RGB':
img = img.convert('RGB')
# Convert to CMYK
cmyk_img = img.convert('CMYK')
cmyk_img.save(cmyk_output_path, format='TIFF', compression='tiff_lzw')
print(f"Converted to CMYK: {cmyk_output_path}")
def apply_srgb_profile(image_path, output_path):
"""Apply sRGB profile for web."""
img = Image.open(image_path)
# sRGB profile (embedded in Pillow)
srgb_profile = ImageCms.createProfile('sRGB')
# Convert to sRGB
img_srgb = ImageCms.profileToProfile(
img,
srgb_profile,
srgb_profile,
renderingIntent=ImageCms.Intent.PERCEPTUAL
)
img_srgb.save(output_path)
# ImageMagick for color space conversion
convert input.png -colorspace sRGB output_srgb.png
convert input.png -colorspace CMYK output_cmyk.tiff
# Check color profile
identify -verbose image.png | grep -i colorspace
Esperado: Color space matches publication requirements En caso de fallo: Verify color profile embedded, test print preview
4. Configure Typography
Ensure text is readable and properly formatted:
from PIL import ImageFont
def get_publication_fonts():
"""Load fonts appropriate for publication."""
# Common publication-safe fonts
fonts = {
'serif': 'Times New Roman',
'sans': 'Arial',
'mono': 'Courier New'
}
try:
# Load with proper size for DPI
# At 300 DPI, 12pt = 12 * 300/72 = 50 pixels
base_size_300dpi = 50
font_regular = ImageFont.truetype(f"{fonts['sans']}.ttf", base_size_300dpi)
font_bold = ImageFont.truetype(f"{fonts['sans']} Bold.ttf", base_size_300dpi)
return {'regular': font_regular, 'bold': font_bold}
except:
return {'regular': ImageFont.load_default(), 'bold': ImageFont.load_default()}
# Typography guidelines
typography_specs = {
'minimum_font_size': '8pt', # Readable when printed
'line_width_min': 0.5, # Points, for print clarity
'panel_labels': {
'font': 'Arial Bold',
'size': '12pt',
'position': 'top-left',
'style': 'A, B, C' # Or (a), (b), (c)
},
'axis_labels': {
'font': 'Arial',
'size': '10pt'
},
'legend': {
'font': 'Arial',
'size': '9pt',
'position': 'outside plot area'
}
}
# R publication-quality typography
library(ggplot2)
p <- ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point(size = 2) +
labs(
title = "Fuel Efficiency vs Weight",
x = "Weight (1000 lbs)",
y = "Miles per Gallon"
) +
theme_bw(base_size = 12, base_family = "Arial") +
theme(
plot.title = element_text(size = 14, face = "bold"),
axis.title = element_text(size = 12),
axis.text = element_text(size = 10),
legend.text = element_text(size = 10),
panel.grid.minor = element_blank(),
# Ensure text is black for print
text = element_text(color = "black")
)
Esperado: Text readable at publication size, fonts embedded properly En caso de fallo: Increase font sizes, check font licensing, convert text to outlines
5. Select Appropriate File Format
Choose format based on use case:
def export_multi_format(source_path, output_base, formats=['png', 'pdf', 'tiff']):
"""Export graphic in multiple formats."""
from PIL import Image
import cairosvg
import os
base, ext = os.path.splitext(output_base)
if ext.lower() in ['.svg']:
# SVG source - convert to rasters
for fmt in formats:
output = f"{base}.{fmt}"
if fmt == 'png':
cairosvg.svg2png(
url=source_path,
write_to=output,
output_width=2126, # 180mm @ 300 DPI
output_height=1417 # 120mm @ 300 DPI
)
elif fmt == 'pdf':
cairosvg.svg2pdf(url=source_path, write_to=output)
elif fmt == 'tiff':
# Convert via PNG intermediate
temp_png = f"{base}_temp.png"
cairosvg.svg2png(url=source_path, write_to=temp_png)
img = Image.open(temp_png)
img.save(output, format='TIFF', compression='tiff_lzw')
os.remove(temp_png)
else:
# Raster source
img = Image.open(source_path)
for fmt in formats:
output = f"{base}.{fmt}"
if fmt == 'png':
img.save(output, format='PNG', dpi=(300, 300), optimize=True)
elif fmt == 'tiff':
img.save(output, format='TIFF', compression='tiff_lzw', dpi=(300, 300))
elif fmt == 'pdf':
# Use img2pdf or similar for raster-to-PDF
img.save(output, format='PDF', resolution=300.0)
print(f"Exported in formats: {', '.join(formats)}")
# Format selection guide
format_guide = {
'TIFF': {
'use_for': 'Journal submission, archival',
'benefits': 'Lossless, supports CMYK, high quality',
'compression': 'LZW or ZIP (lossless)'
},
'PDF': {
'use_for': 'Submission, print, archival',
'benefits': 'Vector or raster, text searchable, widely accepted',
'variants': 'PDF/A (archival), PDF/X (print)'
},
'PNG': {
'use_for': 'Web, presentations, digital',
'benefits': 'Lossless, transparency, good compression',
'limitation': 'RGB only, larger than JPEG'
},
'SVG': {
'use_for': 'Web, further editing, scalable graphics',
'benefits': 'Vector, infinitely scalable, small file size',
'limitation': 'Not always accepted by journals'
},
'EPS': {
'use_for': 'Legacy journal requirements',
'benefits': 'Vector format accepted by older systems',
'limitation': 'Being phased out, use PDF instead'
}
}
Esperado: Appropriate format for publication channel En caso de fallo: Check publisher requirements, provide multiple formats
6. Optimize for Web
Create web-optimized versions:
def optimize_for_web(input_path, output_path, max_width=1200, quality=85):
"""Optimize image for web publication."""
from PIL import Image
img = Image.open(input_path)
# Resize if too large
if img.width > max_width:
ratio = max_width / img.width
new_height = int(img.height * ratio)
img = img.resize((max_width, new_height), Image.LANCZOS)
# Convert to RGB if needed
if img.mode in ('RGBA', 'LA', 'P'):
background = Image.new('RGB', img.size, (255, 255, 255))
if img.mode == 'P':
img = img.convert('RGBA')
background.paste(img, mask=img.split()[-1] if 'A' in img.mode else None)
img = background
# Save optimized
img.save(output_path, format='JPEG', quality=quality, optimize=True, progressive=True)
# Check file size
import os
file_size_kb = os.path.getsize(output_path) / 1024
print(f"Optimized: {file_size_kb:.1f} KB")
def create_responsive_set(input_path, output_base):
"""Create multiple resolutions for responsive web."""
from PIL import Image
img = Image.open(input_path)
sizes = [
(640, '640w'),
(1024, '1024w'),
(1920, '1920w')
]
for width, suffix in sizes:
if img.width >= width:
ratio = width / img.width
height = int(img.height * ratio)
resized = img.resize((width, height), Image.LANCZOS)
output = f"{output_base}_{suffix}.jpg"
resized.save(output, format='JPEG', quality=85, optimize=True)
Esperado: Web-optimized images under 500KB, responsive sizes generated En caso de fallo: Reduce quality, resize further, consider WebP format
7. Embed Metadata
Add descriptive metadata for archival:
from PIL import Image
from PIL.PngImagePlugin import PngInfo
def embed_metadata(image_path, output_path, metadata):
"""Embed metadata in PNG."""
img = Image.open(image_path)
# Create metadata
png_info = PngInfo()
for key, value in metadata.items():
png_info.add_text(key, str(value))
# Save with metadata
img.save(output_path, format='PNG', pnginfo=png_info)
# Example metadata
metadata = {
'Title': 'Figure 1: Relationship between weight and fuel efficiency',
'Author': 'Jane Doe',
'Description': 'Scatter plot showing negative correlation',
'Copyright': 'CC-BY 4.0',
'Software': 'R 4.3.0, ggplot2 3.4.0',
'Creation Date': '2026-02-16',
'Source': 'mtcars dataset'
}
embed_metadata('figure1.png', 'figure1_with_metadata.png', metadata)
Esperado: Metadata embedded and retrievable En caso de fallo: Check format supports metadata (PNG, TIFF, PDF yes; JPEG limited)
Validación
- DPI meets publication requirements (typically 300+)
- Physical dimensions correct for publication
- Color space appropriate (RGB for web, CMYK for print)
- File format accepted by publisher
- Text is readable at publication size
- Fonts embedded or outlined
- Line widths visible when printed
- Color contrast sufficient for grayscale printing
- File size within limits
- Metadata embedded
- Tested print preview or rendering
Errores Comunes
- Insufficient resolution: 72 DPI web graphics cannot be printed at quality
- Wrong color space: RGB graphics may print differently than displayed
- Font substitution: Non-embedded fonts replaced with defaults
- Small text: Fonts below 8pt may be illegible when printed
- Thin lines: Lines below 0.5pt may not print clearly
- File size: High DPI graphics can be very large, compress appropriately
- Compression artifacts: JPEG compression unsuitable for line art or text
- Missing bleed: Print graphics need 3-5mm bleed beyond trim
- Transparency issues: Some formats don't preserve transparency correctly
- Aspect ratio: Distortion from incorrect dimension calculations
Habilidades Relacionadas
- create-2d-composition: Creating the source graphics
- render-blender-output: 3D rendering settings for publication
- generate-quarto-report: Integrating graphics into documents
Repositorio GitHub
Habilidades relacionadas
content-collections
MetaEsta habilidad proporciona una configuración probada en producción para Content Collections, una herramienta centrada en TypeScript que transforma archivos Markdown/MDX en colecciones de datos con tipado seguro mediante validación Zod. Úsala al construir blogs, sitios de documentación o aplicaciones Vite + React con mucho contenido para garantizar seguridad de tipos y validación automática de contenido. Abarca todo, desde la configuración del plugin de Vite y compilación MDX hasta la optimización de despliegue y validación de esquemas.
polymarket
MetaEsta habilidad permite a los desarrolladores crear aplicaciones con la plataforma de mercados de predicción Polymarket, incluyendo la integración de API para operaciones y datos de mercado. También proporciona transmisión de datos en tiempo real a través de WebSocket para monitorear operaciones en vivo y actividad del mercado. Úsela para implementar estrategias de trading o crear herramientas que procesen actualizaciones de mercado en tiempo real.
creating-opencode-plugins
MetaEsta habilidad ayuda a los desarrolladores a crear complementos de OpenCode que se conectan a más de 25 tipos de eventos, como comandos, archivos y operaciones LSP. Proporciona la estructura del complemento, las especificaciones de la API de eventos y los patrones de implementación para módulos en JavaScript/TypeScript. Úsala cuando necesites interceptar, monitorear o extender el ciclo de vida del asistente de IA de OpenCode con lógica personalizada basada en eventos.
sglang
MetaSGLang es un framework de alto rendimiento para el servicio de LLM que se especializa en generación rápida y estructurada para JSON, expresiones regulares y flujos de trabajo de agentes utilizando su caché de prefijos RadixAttention. Ofrece una inferencia significativamente más rápida, especialmente para tareas con prefijos repetidos, lo que lo hace ideal para salidas complejas y estructuradas, y conversaciones multiturno. Elige SGLang sobre alternativas como vLLM cuando necesites decodificación restringida o estés construyendo aplicaciones con uso extensivo de prefijos compartidos.
