Aller au contenu principal
~/GiwiSoft
Qag3x8qag3x8qag3

Afficher un Tif dans un navigateur

Giwi 4 min de lecture Java, Web

L’autre jour j’ai eu la problématique suivante : comment afficher un Tif dans un navigateur web ?

Le problème est que les navigateurs respectent (en tout cas essayent) les normes du W3C et donc ne savent afficher que les Jpeg, les Gif et les Png (et encore, IE a du mal). Voici une solution :

L’idée est de lire un fichier Tif, le convertir en autre chose de lisible par le navigateur et enfin d’écrire cet autre chose dans le stream de réponse du serveur. Evidement, la solution que je propose est en Java.

Je me suis inspiré de ce TechTip (comment ça, encore?).

Etape 1 : JSP

On commence par la jsp d’appel :

<a href="/servlet/tiffServlet?url=<%= tifEncodedUrl %>" >toto.tif</a>

Etape 2: les imports

Je n’ai mis que les plus importants

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

Etape 3 : lire un fichier Tif

Pour ce faire, je me suis appuyer sur la librairie Tiff de Lizzard Works.

// hop, on récupère le paramètre depuis la jsp
final String urlPath = request.getParameter("url");
// on vérifie qu'il y a bien quelque chose dedans
if (urlPath != null && StringUtils.isNotEmpty(urlPath)) {
// Attention on est côté serveur, donc, pas de librairie
// graphique native de disponible!
System.setProperty("java.awt.headless", "true");

final Tiff tiff = new Tiff();
final URL url = new URL(urlPath);
final URLConnection connection = url.openConnection();
connection.connect();
// Une fois qu'on a la connexion vers la ressource distante,
// on branche le tuyau sur l'objet Tif.
final InputStream imgIn = connection.getInputStream();
tiff.readInputStream(imgIn);

Ici, j’ai choisi d’aller chercher un Tif distant. Rien n’empèche de récupérer un stream sur un resource locale.

Etape 4 : Convertir le fichier Tif en Png

C’est là que réside l’astuce. Même si on est en environnement Servlet, on a accès aux bibliothèques Swing et Awt de la JVM ;-)

  // Objet Image d'awt
Image img = tiff.getImage(tiff.getPageCount() - 1);

// Canevas servant d'ImageObserver
final Canvas iob = new Canvas();

// On "dessine" l'image dans l'ImageObserver
g2.drawImage(img, 0, 0, img.getWidth(iob), img.getHeight(iob),
Color.white, iob);

// On récupère l'image et on la crée.
BufferedImage bi = new BufferedImage(img.getWidth(iob), 
img.getHeight(iob),
BufferedImage.TYPE\_INT\_RGB);
Graphics2D g2 = bi.createGraphics();
try {
// On récupère le tuyau de sortie
ServletOutputStream out = response.getOutputStream();

// On anonce la couleur au navigateur
response.setContentType("image/png");

// Et hop, on envoie la sauce, notre objet Image est converti en png
ImageIO.write(bi, "png", out);

out.flush();
out.close();
} catch (final IOException ex) {
ex.printStackTrace();
}
} // parenthèse du if de la ligne4 de l'étape 3\[/codesyntax\]

Etape 5 : tout le monde est content

Rien n’empèche d’ajouter du LightBox dans la jsp, en tout cas, on va chercher un Tif et le navigateur affiche un Png. Magique non?

Voici mes sources :


Solutions modernes (2024)

1. Conversion avec ImageMagick

La manière la plus simple aujourd’hui :

convert input.tif output.png
# ou pour du JPEG
convert input.tif -quality 90 output.jpg
# conversion par lots
for f in *.tif; do convert "$f" "${f%.tif}.png"; done

2. Bibliothèque JavaScript tiff.js

tiff.js permet de décoder et afficher des TIFF côté client, sans serveur :

const Tiff = require('tiff.js');
const tiff = new Tiff({ buffer: arrayBuffer });
const canvas = document.getElementById('canvas');
canvas.width = tiff.width();
canvas.height = tiff.height();
const ctx = canvas.getContext('2d');
ctx.drawImage(tiff.toCanvas(), 0, 0);

3. Conversion streamée avec Sharp (Node.js)

Sharp est la librairie de référence pour le traitement d’images en Node.js :

const sharp = require('sharp');

// TIF vers PNG, streamé
sharp('input.tif')
.png()
.toFile('output.png');

// TIF vers JPEG avec redimensionnement
sharp('input.tif')
.resize(800, 600)
.jpeg({ quality: 85 })
.toBuffer()
.then(data => res.end(data));

4. Support navigateur pour TIFF

En 2024, aucun navigateur ne supporte nativement le TIFF. La solution reste la conversion côté serveur ou l’utilisation de wasm côté client. Les formats WebP et AVIF sont les alternatives modernes recommandées pour l’archivage d’images sur le web.