Communitygithub.com

Sunrich-HT/figure-extractor

Extrai figuras e imagens completas de PDFs, artigos arXiv e páginas HTML — uma habilidade de agente de IA para Claude Code, Codex e Kimi. Usa legendas e bounding boxes com PyMuPDF em alta resolução para recorte, além de gerar um contact sheet para controle de qualidade.

O que é figure-extractor?

Esta habilidade permite que agentes de IA (como Claude Code, Codex e Kimi) extraiam figuras e imagens completas de PDFs, artigos do arXiv e páginas HTML de forma automatizada. Diferente de métodos simplistas que apenas extraem imagens embutidas no PDF (que frequentemente são fragmentos incompletos de vetores e texto), a ferramenta utiliza um pipeline inteligente: localiza legendas como 'Figura 2.1' ou 'Extended Data Fig. 1', analisa o grid de colunas da página, determina o bounding box adequado para cada figura, renderiza a página em 300 DPI com PyMuPDF e recorta precisamente cada figura. O resultado inclui arquivos PNG, um manifest.json detalhando o status de cada extração (com suporte e falha), e um contact_sheet.jpg para inspeção visual. A habilidade suporta entrada por PDF local, URLs de PDF, URLs do arXiv (/abs/ → /pdf/ automaticamente) e URLs HTML. Também oferece um modo degradado para ambientes sem shell ou Python, onde o agente fornece links diretos e descrições textuais das figuras. A ferramenta é instalada via pip e executada na linha de comando — não é um serviço hospedado ou função in-agent.

Funciona com✓Claude Code✓Codex CLI~Cursor
npx skills add Sunrich-HT/figure-extractor

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Habilidade Extrator de Figuras

Use esta habilidade quando o usuário precisar extrair figuras ou imagens completas de PDFs, artigos arXiv ou páginas HTML de artigos.

O que esta habilidade realmente é (leia primeiro)

figure-extractor é uma ferramenta de linha de comando (Python + PyMuPDF). "Usá-la" significa executar sua CLI em um shell — por exemplo figure-extractor extract paper.pdf. Ela não é uma função chamável dentro do agente, um serviço hospedado ou uma "página" que você ativa, e não pode ser executada em um runtime que não possui shell ou não pode instalar pacotes Python (por exemplo, Agente Notion, agentes apenas em navegador).

Contrato de invocação

  • Mecanismo: comando de shell figure-extractor <subcomando> ... (instalado via pip install -e .).
  • Entrada: um caminho local de PDF/HTML ou uma URL de PDF/arXiv/HTML.
  • Saída: arquivos PNG + manifest.json + contact_sheet.jpg (+ opcionalmente figures.zip) escritos em --out.

Etapa 0 — verificação de pré-condição (sempre faça isso primeiro)

Antes de prometer a extração de figuras, verifique se a ferramenta pode realmente ser executada neste ambiente:

figure-extractor --help     # se isso der erro, ou não houver shell, a ferramenta está INDISPONÍVEL
  • Disponível (comando executa) → siga o Algoritmo preferido.
  • Indisponível (sem shell / não instalado / em sandbox) → vá para Modo degradado. Não ter a ferramenta não é uma falha e não é uma violação de regra — degrade graciosamente e informe ao usuário o que você fez.

Regra principal (quando o extrator estiver disponível)

Não confie apenas na extração de imagens embutidas no PDF. Muitas figuras são compostas por desenhos vetoriais, rótulos de texto, legendas e fragmentos raster. A extração de imagens embutidas frequentemente retorna fragmentos incompletos — prefira o pipeline de recorte por renderização com bounding box de legenda abaixo.

Algoritmo preferido (requer um shell + a CLI)

  1. Resolva a fonte de entrada:
    • PDF local
    • URL de PDF
    • URL de resumo do arXiv (/abs/ é normalizado automaticamente para /pdf/)
    • URL HTML
    • HTML local
  2. Se HTML estiver disponível, primeiro tente extrair imagens de figuras originais de atributos <figure>, <img>, <picture>, srcset e carregamento preguiçoso.
  3. Se o HTML não fornecer figuras de alta qualidade suficientes, localize ou baixe o PDF.
  4. Para PDFs:
    • localize cada legenda: Figure 2.1, Figure B.1, Extended Data Fig. 1, Supplementary Table S3, Scheme/Algorithm/Listing/Box, 图 1;
    • recupere o grid de colunas da página e confine cada recorte à faixa de sua legenda;
    • expanda o bounding box a partir de primitivas gráficas, parando em outras legendas e texto corrido;
    • renderize a página a 300 dpi e recorte;
    • gere PNGs, manifest.json e contact_sheet.jpg.
  5. Leia o campo status de cada entrada em manifest.json. Qualquer item marcado como suspect ou failed carrega quality_reasons explicando o que deu errado. Não apresente um recorte failed ao usuário como se fosse a figura.
  6. Se um recorte estiver errado, corrija-o com crop --bbox, partindo do bounding box que o manifesto já registrou.

Modo degradado (sem shell / CLI indisponível / bitmap inacessível)

Use este modo quando você não puder executar figure-extractor (sem shell, sem Python/pip, ambiente em sandbox), ou quando não puder executar nada que recupere o bitmap real (por exemplo, o HTML remove <img> src, URLs de imagem do arXiv retornam 404, página atrás de autenticação). Este caminho é explicitamente permitido e não conta como violação da "regra principal":

  1. Link para o original. Forneça a URL direta da figura, a página de origem ou o número da página do PDF do arXiv + número da figura para que o usuário possa abrir a imagem real.
  2. Descreva fielmente. Dê uma leitura estruturada de cada figura a partir de sua legenda + texto ao redor: o que mostra, eixos/painéis/legenda, tendência principal. Nunca invente conteúdo de figura que você não pôde ver de fato.
  3. Identifique a lacuna. Diga claramente, por exemplo: Bitmap não embutido — motivo: nenhum shell disponível (ou imagem 404, src removido pelo sanitizador, requer autenticação).

Saída degradada = link original + descrição estruturada fiel + uma nota explícita "por que o bitmap está faltando". Esse é um resultado aceitável, não uma violação.

Configuração

Um pacote ausente não é motivo para degradar — instale-o. O conjunto de dependências é pequeno (PyMuPDF, Pillow, beautifulsoup4); sem GPU, sem modelo, sem serviço.

pip install git+https://github.com/Sunrich-HT/figure-extractor

A partir de um checkout: pip install -e .

Tem um PDF? Execute-o no PDF.

Se o usuário anexou um PDF, ou você pode baixar um, esse é o caminho mais simples e confiável. Não comece com HTML ou navegador.

figure-extractor extract <caminho-do-pdf> --out ./figures --dpi 300 --zip

Apenas quando nenhum PDF for obtido você deve tentar a rota HTML. Observe que alguns ambientes de busca HTML removem <img src>, deixando apenas texto — quando isso acontecer, pare de trabalhar com o HTML e volte a buscar o PDF.

Comandos

# Extração automática (PDF local, URL de PDF, URL de resumo arXiv ou artigo HTML)
figure-extractor extract paper.pdf --out ./figures --dpi 300 --zip
figure-extractor extract https://arxiv.org/abs/2606.23443 --out ./figures --zip
figure-extractor extract https://openreview.net/forum?id=XXXX --out ./figures
figure-extractor extract https://example.com/article --prefer html --fallback pdf

# Apenas figuras, ou apenas os recortes com maior probabilidade de serem relevantes
figure-extractor extract paper.pdf --kinds figure --tiers A,B

# Correção manual de bounding box para uma única figura
figure-extractor crop paper.pdf --page 5 --bbox 295,245,556,475 --out fig04.png --dpi 300

Configurações padrão

  • dpi: 300
  • margin: 8 pontos PDF
  • prefer: auto
  • fallback: pdf
  • kinds: all — extração é exaustiva por padrão
  • tiers: A,B,C — nada filtrado por padrão; o nível é um sinal de triagem, não um julgamento sobre quais itens carregam o argumento
  • contact_sheet: true

Orientações de controle de qualidade

Quando o extrator for executado, sempre inspecione contact_sheet.jpg e o status de cada entrada do manifesto. Recortes suspect e failed são sinalizados em laranja e vermelho na folha. Se uma figura incluir texto corporal ao redor ou perder parte da figura, reexecute crop com um bounding box manual.

O manifesto contabiliza cada candidato que a ferramenta viu. Se containers_found exceder o que foi renderizado, a lista dropped diz por que cada um não foi — trate uma lacuna inexplicada como um bug, não como uma execução limpa.

Habilidades Relacionadas