Nenhuma dessas ferramentas atendeu aos meus requisitos, então escrevi uma que usa a minúscula biblioteca de imagens de Mark Tylers, mtpixel (agora parte do mtcelledit ). Não é muito extensa, mas é facilmente extensível através das funções internas do mtpixel que incluem: escala de cinza, inversão de cores , rotação, nitidez, quantizar, posterizar, inverter (vertical e horizontal), transformar, rgb-> indexado, indexado-> rgb, detecção de borda, relevo, desenho de polígonos, texto e muito mais.
Tudo o que você faz é passar um conjunto de imagens como args (suporta png, gif e jpeg) e ele produzirá um png rgb chamado sprite.png, juntamente com os dados úteis de corte de imagem no stdout. Eu o uso em scripts bash para criar um diretório inteiro de imagens e gerar os dados de corte para geração automática de css (com a esperança de eventualmente torná-lo capaz de substituir automaticamente as tags img existentes automagicamente por um pouco de sed / awk criativo)
Pacotes binários para filhotes linux estarão aqui:
http://murga-linux.com/puppy/viewtopic.php?t=82009
Meu caso de uso exigia unir as imagens verticalmente em um novo png, de modo que é tudo o que faz, mas meu código-fonte é de domínio público e a biblioteca mtcelledit é gpl3. Com o mtpixel vinculado estaticamente, o binário é <100kb (apenas alguns kb quando vinculado dinamicamente) e as únicas outras dependências são libpng, libjpeg e libgif (e tipo livre com o mtpixel oficial, mas eu não precisava do suporte de texto, por isso comentou os bits do tipo livre na compilação estática)
sinta-se à vontade para modificar para suas próprias necessidades:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <mtpixel.h>
int main( int argc, char *argv[] ){
int i=0,height=0,width=0,y=0;
mtpixel_init();
mtImage *imglist[argc];
argc--;
do{ imglist[i] = mtpixel_image_load( argv[i+1] );
height+=imglist[i]->height;
if (imglist[i]->width > width) width=imglist[i]->width;
} while (++i < argc);
imglist[argc]=mtpixel_image_new_rgb(width,height);
imglist[argc]->palette.trans=0;
i=0;
do{ if (imglist[i]->type == MTPIXEL_IMAGE_INDEXED)
mtpixel_image_paste(imglist[argc],mtpixel_image_to_rgb(imglist[i]),mtpixel_brush_new(),0 ,y);
else mtpixel_image_paste(imglist[argc],imglist[i],mtpixel_brush_new(),0 ,y);
printf("name=%s;width=%d;height=%d;y_offset=%d\n",argv[i+1],imglist[i]->height,imglist[i]->width,y);
y+=imglist[i]->height;
mtpixel_image_destroy( imglist[i] );
}while (++i < argc);
mtpixel_image_save( imglist[argc], "sprite.png", MTPIXEL_FILE_TYPE_PNG, 5 );
mtpixel_quit();
return 0;
}