Comment combiner des images sans les charger dans la RAM en Java


J'ai une très grande image (autour d'un gigapixel) que j'essaie de générer, et jusqu'à présent, je ne peux créer que des images jusqu'à environ 40 mégapixels dans une image tampon avant d'obtenir une erreur de mémoire. Je veux construire l'image pièce par pièce, puis combiner les pièces sans charger les images en mémoire. Je pourrais aussi le faire en écrivant chaque morceau dans un fichier, mais ImageIO ne le supporte pas.

Author: Fractaly, 2011-10-06

4 answers

Je pense JAI peut vous aider à construire ce que vous voulez. Je suggère de regarder les structures de données et les flux offerts par JAI.

Aussi, jetez un oeil à ces questions, pourrait vous aider avec des idées.

  1. Comment enregistrer une grande image fractale avec le moins de mémoire possible l'empreinte
  2. Comment créer un gros fichier image à partir de plusieurs morceaux
  3. Ajout à un fichier Image

Vous voulez essentiellement inverser 2 y.
Bonne chance avec votre projet ;)

 1
Author: c00kiemon5ter, 2017-05-23 10:29:23

Pas une bonne solution, juste un croquis.

Le déballage d'une image n'est pas facile lorsqu'une image est compressée. Vous pouvez décompresser, par un outil externe, l'image dans un format trivial (xpm, tiff non compressé). Ensuite, vous pouvez charger des morceaux de cette image sous forme de tableaux d'octets, car le format est si simple, et créer des instances d'image à partir de ces données brutes.

 0
Author: 9000, 2011-10-05 23:53:43

Je vois deux solutions faciles. Créez un format binaire personnalisé pour votre image. Pour enregistrer, il suffit de générer une partie à la fois, de seek() à l'endroit approprié dans le fichier, puis de décharger vos données. Pour le chargement, seek () à l'endroit approprié dans le fichier, puis chargez vos données.

L'autre solution consiste à apprendre vous-même un format d'image. bmp est non compressé, mais le seul facile à apprendre. Une fois apprises, les étapes ci-dessus fonctionnent assez bien.

N'oubliez pas de convertir votre image en un tableau d'octets pour le stockage facile.

 0
Author: warren, 2012-12-14 23:46:43

S'il n'y a aucun moyen de le faire intégré dans Java (pour votre bien, j'espère que ce n'est pas le cas et que quelqu'un répond en le disant), alors vous devrez implémenter vous-même un algorithme, tout comme d'autres l'ont commenté ici en le disant.

Vous n'avez pas nécessairement besoin de comprendre l'ensemble de l'algorithme vous-même. Si vous prenez un algorithme préexistant, vous pouvez simplement le modifier pour charger le fichier en tant que flux d'octets, créer un tampon d'octets pour continuer à lire des morceaux du fichier et modifier l'algorithme pour acceptez ces données un morceau à la fois.

Certains algorithmes, tels que jpg, peuvent ne pas être implémentés avec un flux linéaire de morceaux de fichiers de cette manière. Comme @ warren l'a suggéré, bmp est probablement le plus facile à implémenter de cette manière car ce format de fichier a juste un en-tête de tant d'octets, puis il vide simplement les données RGBA directement au format binaire (avec un peu de remplissage). Donc, si vous deviez charger vos sous-images qui doivent être combinées, chargez-les logiquement 1 à la fois (bien que vous pouvez en fait multithread cette chose et charger les données suivantes simultanément pour l'accélérer, car ce processus va prendre beaucoup de temps), lire la ligne de données suivante, enregistrer cela dans votre flux de sortie binaire, etc.

Vous devrez peut-être même charger les sous-images plusieurs fois. Par exemple, imaginez une image en cours d'enregistrement qui est composée de 4 sous-images dans une grille 2x2. Vous devrez peut-être charger l'image 1, lire sa première ligne de données, l'enregistrer dans votre nouveau fichier, libérer l'image 1, chargez l'image 2, lisez sa première ligne de données, sauvez, libérez 2, chargez 1 pour lire sa 2ème ligne de données, et ainsi de suite. Vous seriez plus susceptibles d'avoir besoin de faire cela si vous utilisez un format d'image compressé pour l'épargne.

Pour suggérer à nouveau un bmp, puisque le bmp n'est pas compressé et que vous pouvez simplement enregistrer les données dans le format de votre choix( en supposant que le fichier a été ouvert de manière à fournir un accès aléatoire), vous pouvez sauter dans le fichier que vous enregistrez afin de pouvoir lire complètement 1 sous-image et sauvegarder toutes ses données avant de passer à la suivante. Cela pourrait permettre d'économiser du temps d'exécution, mais cela pourrait également fournir de terribles tailles de fichiers enregistrés.

Et je pourrais continuer. Il y aura probablement de multiples pièges, optimisations, etc.

Au lieu d'enregistrer 1 énorme fichier qui est le résultat de la combinaison d'autres fichiers, et si vous créiez un nouveau format de fichier image qui était simplement composé de méta-données lui permettant de référencer d'autres fichiers d'une manière qui les combinait logiquement sans en fait, créer 1 fichier massif? Que la création d'un nouveau format de fichier image soit ou non une option dépend de votre logiciel; si vous vous attendez à ce que les gens prennent ces images pour les utiliser dans d'autres logiciels, cela ne fonctionnerait pas - du moins, pas à moins que vous puissiez obtenir votre nouveau format de fichier image pour attraper et devenir standard.

 0
Author: Aaron, 2017-01-18 21:52:25