2010-08-11 5 views
2

J'essaye de faire une manipulation (en particulier, la conversion à un type différent de découpage en tuiles) sur un ensemble de très grands fichiers d'image BMP (quelques Go).Comment puis-je faire de la manipulation d'image sur un très gros BMP?

Je ne suis pas sûr de comprendre le format de fichier BMP, mais est-il nécessaire de charger le fichier entier en mémoire? J'ai été incapable de trouver une API qui n'a pas besoin de charger le fichier entier à un moment donné. ImageMagick n'était pas capable de le faire non plus. Java serait le meilleur outil de choix pour moi, mais toute autre solution, y compris les outils en ligne de commande ou les logiciels de bureau serait acceptable.

+0

Quelles transformations voulez-vous faire? Certains peuvent être effectués avec une fenêtre de décalage, de sorte que vous n'avez pas besoin de tout charger. D'autres pourraient permettre le streaming, et certains pourraient en avoir besoin :) – extraneon

+0

rien de grave, se scinder en dalles, ou convertir en un format plus compressé – Ovesh

Répondre

2

Basé sur this, il devrait être raisonnablement évident que vous pouvez utiliser le fait qu'il est emballé en rangées. Vous devriez être capable de lire une partie d'une rangée, de la stocker, d'avancer à la même position dans la rangée suivante et de répéter jusqu'à ce que vous ayez complété une tuile de la taille désirée. Évidemment, vous pouvez être en mesure de faire plusieurs tuiles à la fois si vous pouvez stocker une ligne entière de tuiles en mémoire en une seule fois.

Il n'est pas nécessaire de charger plus de l'en-tête du fichier à la fois. Le format d'en-tête est décrit dans l'entrée Wikipedia liée. Il est probablement utile de faire attention à tous les schémas de compression utilisés - la compression est susceptible de rendre cette tâche un peu plus difficile (mais pas toujours impossible) :)

1

Pas sûr de l'année 2011 de cette quête, mais Java 7 (et peut-être 6) a une bonne approche pour un tel plaisir.

Utilisez les classes ImageReader et ImageReadParam, elles permettent de lire toute partie rectangulaire de l'image source si nécessaire. Définir rectangle source et lire

... // initialization 

private javax.imageio.ImageReadParam m_params; 
private javax.imageio.ImageReader m_reader; 

... // reading 

m_params.setSourceRegion(readRect); 
BufferedImage rdImg = m_reader.read(i, m_params); 

... // processing/displaying etc 

BMP (cela fonctionne aussi pour tout type d'image Java standard) est le format très plan sans aucune compression dans 99,99% des cas, à lire toute sa part de telle manière est processus très rapide avec une faible consommation de mémoire sauf résultat BufferedImage. Ou vous pouvez même réutiliser l'image tampon précédente à la demande conséquente avec le rect de mêmes dimensions. Voir ImageReadParam.setDestination (destination BufferedImage). Mais je n'ai pas testé cette option.

J'ai aussi trouvé un petit bogue de lecture à savoir dans l'implémentation de la classe de lecteur BMP de Java runtime lib. Si quelqu'un est intéressé par cela, je vais montrer une façon simple de le corriger.

Questions connexes