2010-04-10 4 views

Répondre

3

Displaying fancy equations with Java Generate Images for formulas in Java

En gros, je dirais que vos options sont:

  • Utilisez l'une des bibliothèques Java mentionnées pour la première question, si elles conviennent à l'application et la forme du latex (par exemple, est-ce des documents entiers avec des macros, des fichiers de style et BibTex ou simplement des équations simples).
  • Exécuter texvc comme un programme externe (comme Wikipédia/MediaWiki), ou un lien vers le code OCaml via JNI.

EDIT

Comme Stephen C dit, ceux-ci ne sont que pour des fragments de latex. Si vous voulez convertir un document Latex complet, vous aurez besoin d'une implémentation complète de Latex - rien de tout cela. Et ceux-ci doivent être quelque peu grands et complexes parce qu'ils sont des «environnements de développement» complets pour la composition de documents en écrivant du code Latex. Si c'est ce dont vous avez besoin, vous n'avez pas beaucoup d'autre choix que d'utiliser une des distributions Latex standard via exec (et je suppose que cela échoue gracieusement si l'interpréteur Latex signale des erreurs dans le code Latex). Cela dit, il y a eu au moins quelques tentatives de portage de Latex vers Java (dont deux appelées "JavaTex"). Très probablement ceux-ci ne sont pas dans un état qui vous convient - mais voir le résumé de quelques tentatives récentes de juger par vous-même:

http://www.monperrus.net/martin/running+tex+on+a+java+virtual+machine

0

Il n'est pas impossible de le faire. (Java est complet à Turing ...). Mais il est (IMO) peu probable que vous trouverez une bibliothèque existante pour traiter TeX/LaTeX en Java, et peu pratique pour vous de l'implémenter vous-même.

Je chercherais des applications de ligne de commande qui convertissent TeX/LaTeX en quelque chose (par exemple pdf ou postscript), et puis quelque chose pour png pages d'images. Ensuite, je créer un script wrapper qui combine les applications selon les besoins, et utiliser Process.exec(...) pour exécuter le script.

EDIT

Si vous êtes désireux de rendre des équations mathématiques LaTeX , essayez les options proposées par les réponses liées par @ RD1.

1

Une autre solution consiste à appeler mimetex.cgi (disponible ici: http://www.forkosh.com/mimetex.html) à partir de Java.

Je ne prétends pas que cette solution soit "meilleure" que celles données précédemment, en particulier l'utilisation de JLatexMath. Le but est juste de donner des alternatives.

Exemple de résultat:

enter image description here

code menant à ce résultat:

import java.awt.*; 
import java.io.*; 
import java.util.ArrayList; 
import javax.swing.*; 

public class Exemple106_MimetexInterface { 

private static String MIMETEX_EXE = "c:\\Program Files (x86)\\mimetex\\mimetex.cgi"; 

final private static int BUFFER_SIZE = 1024; 

/** 
* Convert LaTeX code to GIF 
* 
* @param latexString LaTeX code 
* @return GIF image, under byte[] format 
*/ 
public static byte[] getLaTeXImage(String latexString) { 
    byte[] imageData = null; 
    try { 
     // mimetex is asked (on the command line) to convert 
     // the LaTeX expression to .gif on standard output: 
     Process proc = Runtime.getRuntime().exec(MIMETEX_EXE + " -d \"" + latexString + "\""); 
     // get the output stream of the process: 
     BufferedInputStream bis = (BufferedInputStream) proc.getInputStream(); 
     // read output process by bytes blocks (size: BUFFER_SIZE) 
     // and stores the result in a byte[] Arraylist: 
     int bytesRead; 
     byte[] buffer = new byte[BUFFER_SIZE]; 
     ArrayList<byte[]> al = new ArrayList<byte[]>(); 
     while ((bytesRead = bis.read(buffer)) != -1) { 
      al.add(buffer.clone()); 
     } 
     // convert the Arraylist in an unique array: 
     int nbOfArrays = al.size(); 
     if (nbOfArrays == 1) { 
      imageData = buffer; 
     } else { 
      imageData = new byte[BUFFER_SIZE * nbOfArrays]; 
      byte[] temp; 
      for (int k = 0; k < nbOfArrays; k++) { 
       temp = al.get(k); 
       for (int i = 0; i < BUFFER_SIZE; i++) { 
        imageData[BUFFER_SIZE * k + i] = temp[i]; 
       } 
      } 
     } 
     bis.close(); 
     proc.destroy(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return imageData; 
} 

/** 
* demonstration main 
* 
* @param args command line arguments 
*/ 
public static void main(String[] args) { 
    JFrame jframe = new JFrame(); 
    jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    jframe.setLayout(new BorderLayout()); 

    String LATEX_EXPRESSION_1 = "4$A=\\(\\array{3,c.cccBCCC$&1&2&3\\\\\\hdash~1&a_{11}&a_{12}&a_{13}\\\\2&a_{21}&a_{22}&a_{23}\\\\3&a_{31}&a_{32}&a_{33}}\\) "; 
    byte[] imageData1 = getLaTeXImage(LATEX_EXPRESSION_1); 
    JLabel button1 = new JLabel(new ImageIcon(imageData1)); 
    jframe.add(button1, BorderLayout.NORTH); 

    String LATEX_EXPRESSION_2 = "4$\\array{rccclBCB$&f&\\longr[75]^{\\alpha:{-1$f\\rightar~g}}&g\\\\3$\\gamma&\\longd[50]&&\\longd[50]&3$\\gamma\\\\&u&\\longr[75]_\\beta&v}"; 
    byte[] imageData2 = getLaTeXImage(LATEX_EXPRESSION_2); 
    JLabel button2 = new JLabel(new ImageIcon(imageData2)); 
    jframe.add(button2, BorderLayout.CENTER); 

    String LATEX_EXPRESSION_3 = "4$\\hspace{5}\\unitlength{1}\\picture(175,100){~(50,50){\\circle(100)}(1,50){\\overbrace{\\line(46)}^{4$\\;\\;a}}(52,50) {\\line(125)}~(50,52;115;2){\\mid}~(52,55){\\longleftar[60]}(130,56){\\longrightar[35]}~(116,58){r}~(c85,50;80;2){\\bullet} (c85,36){3$-q}~(c165,36){3$q}(42,30){\\underbrace{\\line(32)}_{1$a^2/r\\;\\;\\;}}~}"; 
    byte[] imageData3 = getLaTeXImage(LATEX_EXPRESSION_3); 
    JLabel button3 = new JLabel(new ImageIcon(imageData3)); 
    jframe.add(button3, BorderLayout.SOUTH); 

    jframe.pack(); 
    jframe.setLocationRelativeTo(null); 
    jframe.setVisible(true); 
} 
} 

Nicolas

0

Une autre solution pour créer une image PNG de LATEX à condition que LATEX (pour instance: MiKTeX) est installé sur l'ordinateur ...

Le paquet autonome LaTeX permet la création d'un fichier de sortie PNG, dont la taille correspond exactement à la taille de la formule ou du texte. Donc, il suffit d'appeler LaTeX à partir de Java et d'obtenir le fichier de sortie PNG.

1. Pré-requis

a) doit être installé LATEX sur l'ordinateur
... avec tous les paquets nécessaires pour la formule (dans l'exemple ci-dessous: amsfonts et amsmath)
... avec package autonome

GhostScript doit être installé (nécessaire pour le package autonome)
Le répertoire contenant gswin32c.exe doit être ajouté à PATH.
Sur mon ordinateur: C: \ Program Files (x86) \ gs \ gs9.10 \ bin

ImageMagick doit être installé (nécessaire pour le paquet autonome)
convert.exe est remplacé par l'imgconvert.exe
Le répertoire contenant imgconvert.exe doit être ajouté à PATH.
Sur mon ordinateur: C: \ Program Files (x86) \ ImageMagick-6.8.8-9

2. Vérifiez que LATEX (avec le package autonome) réussit à générer le fichier PNG (pas Java à ce stade) .

Référence: https://tex.stackexchange.com/questions/11866/compile-a-latex-document-into-a-png-image-thats-as-short-as-possible

fichier LaTeX, appelé New21.tex (par exemple):

\documentclass[border=0.50001bp,convert={convertexe={imgconvert},outext=.png}]{standalone} 

\usepackage{amsfonts} 

\usepackage{amsmath} 

\begin{document} 

$\begin{array}{l} 

\forall\varepsilon\in\mathbb{R}_+^*\ \exists\eta>0\ |x-x_0|\leq\eta\Longrightarrow|f(x)-f(x_0)|\leq\varepsilon\\ 

\det\begin{bmatrix}a_{11}&a_{12}&\cdots&a_{1n}\\a_{21}&\ddots&&\vdots\\\vdots&&\ddots&\vdots\\a_{n1}&\cdots&\cdots&a_{nn}\end{bmatrix}\overset{\mathrm{def}}{=}\sum_{\sigma\in\mathfrak{S}_n}\varepsilon(\sigma)\prod_{k=1}^n a_{k\sigma(k)}\\ 

{\sideset{_\alpha^\beta}{_\gamma^\delta}{\mathop{\begin{pmatrix}a&b\\c&d\end{pmatrix}}}}\\ 

\int_0^\infty{x^{2n} e^{-a x^2}\,dx} = \frac{2n-1}{2a} \int_0^\infty{x^{2(n-1)} e^{-a x^2}\,dx} = \frac{(2n-1)!!}{2^{n+1}} \sqrt{\frac{\pi}{a^{2n+1}}}\\ 

\int_a^b{f(x)\,dx} = (b - a) \sum\limits_{n = 1}^\infty {\sum\limits_{m = 1}^{2^n - 1} {\left({ - 1} \right)^{m + 1} } } 2^{ - n} f(a + m\left({b - a} \right)2^{-n})\\ 

\int_{-\pi}^{\pi} \sin(\alpha x) \sin^n(\beta x) dx = \textstyle{\left \{ \begin{array}{cc} (-1)^{(n+1)/2} (-1)^m \frac{2 \pi}{2^n} \binom{n}{m} & n \mbox{ odd},\ \alpha = \beta (2m-n) \\ 0 & \mbox{otherwise} \\ \end{array} \right .}\\ 

L = \int_a^b \sqrt{ \left|\sum_{i,j=1}^ng_{ij}(\gamma(t))\left(\frac{d}{dt}x^i\circ\gamma(t)\right)\left(\frac{d}{dt}x^j\circ\gamma(t)\right)\right|}\,dt\\ 

\begin{array}{rl} s &= \int_a^b\left\|\frac{d}{dt}\vec{r}\,(u(t),v(t))\right\|\,dt \\ &= \int_a^b \sqrt{u'(t)^2\,\vec{r}_u\cdot\vec{r}_u + 2u'(t)v'(t)\, \vec{r}_u\cdot\vec{r}_v+ v'(t)^2\,\vec{r}_v\cdot\vec{r}_v}\,\,\, dt. \end{array}\\ 

\end{array}$ 

\end{document} 

Ligne de commande:

pdflatex -shell-escape New21.tex 

Cela devrait générer un fichier contenant New21.png l'image ci-dessous: enter image description here

3. Génération du fichier PNG à partir de Java, via un appel à LaTeX

Code:

import java.awt.FlowLayout; 
import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 

class StreamPrinter implements Runnable { 

    // Source: http://labs.excilys.com/2012/06/26/runtime-exec-pour-les-nuls-et-processbuilder/ 
    private final InputStream inputStream; 

    private boolean print; 

    StreamPrinter(InputStream inputStream, boolean print) { 
     this.inputStream = inputStream; 
     this.print = print; 
    } 

    private BufferedReader getBufferedReader(InputStream is) { 
     return new BufferedReader(new InputStreamReader(is)); 
    } 

    @Override 
    public void run() { 
     BufferedReader br = getBufferedReader(inputStream); 
     String ligne = ""; 
     try { 
      while ((ligne = br.readLine()) != null) { 
       if (print) { 
        System.out.println(ligne); 
       } 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

public class Exemple141_LaTeX_to_PNG_using_installed_LaTeX_distribution { 

    public static void main(String[] args) { 

     String TEMP_DIRECTORY = "D:\\_tmp"; 
     String TEMP_TEX_FILE_NAME = "New22"; // for New22.tex 

     // 1. Prepare the .tex file 
     String newLineWithSeparation = System.getProperty("line.separator")+System.getProperty("line.separator"); 
     String math = ""; 
     math += "\\documentclass[border=0.50001bp,convert={convertexe={imgconvert},outext=.png}]{standalone}" + newLineWithSeparation; 
     math += "\\usepackage{amsfonts}" + newLineWithSeparation; 
     math += "\\usepackage{amsmath}" + newLineWithSeparation; 
     math += "\\begin{document}" + newLineWithSeparation; 
     math += "$\\begin{array}{l}" + newLineWithSeparation; 
     math += "\\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\" + newLineWithSeparation; 
     math += "\\det\\begin{bmatrix}a_{11}&a_{12}&\\cdots&a_{1n}\\\\a_{21}&\\ddots&&\\vdots\\\\\\vdots&&\\ddots&\\vdots\\\\a_{n1}&\\cdots&\\cdots&a_{nn}\\end{bmatrix}\\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\" + newLineWithSeparation; 
     math += "{\\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\\mathop{\\begin{pmatrix}a&b\\\\c&d\\end{pmatrix}}}}\\\\" + newLineWithSeparation; 
     math += "\\int_0^\\infty{x^{2n} e^{-a x^2}\\,dx} = \\frac{2n-1}{2a} \\int_0^\\infty{x^{2(n-1)} e^{-a x^2}\\,dx} = \\frac{(2n-1)!!}{2^{n+1}} \\sqrt{\\frac{\\pi}{a^{2n+1}}}\\\\" + newLineWithSeparation; 
     math += "\\int_a^b{f(x)\\,dx} = (b - a) \\sum\\limits_{n = 1}^\\infty {\\sum\\limits_{m = 1}^{2^n - 1} {\\left({ - 1} \\right)^{m + 1} } } 2^{ - n} f(a + m\\left({b - a} \\right)2^{-n})\\\\" + newLineWithSeparation; 
     math += "\\int_{-\\pi}^{\\pi} \\sin(\\alpha x) \\sin^n(\\beta x) dx = \\textstyle{\\left \\{ \\begin{array}{cc} (-1)^{(n+1)/2} (-1)^m \\frac{2 \\pi}{2^n} \\binom{n}{m} & n \\mbox{ odd},\\ \\alpha = \\beta (2m-n) \\\\ 0 & \\mbox{otherwise} \\\\ \\end{array} \\right .}\\\\" + newLineWithSeparation; 
     math += "L = \\int_a^b \\sqrt{ \\left|\\sum_{i,j=1}^ng_{ij}(\\gamma(t))\\left(\\frac{d}{dt}x^i\\circ\\gamma(t)\\right)\\left(\\frac{d}{dt}x^j\\circ\\gamma(t)\\right)\\right|}\\,dt\\\\" + newLineWithSeparation; 
     math += "\\begin{array}{rl} s &= \\int_a^b\\left\\|\\frac{d}{dt}\\vec{r}\\,(u(t),v(t))\\right\\|\\,dt \\\\ &= \\int_a^b \\sqrt{u'(t)^2\\,\\vec{r}_u\\cdot\\vec{r}_u + 2u'(t)v'(t)\\, \\vec{r}_u\\cdot\\vec{r}_v+ v'(t)^2\\,\\vec{r}_v\\cdot\\vec{r}_v}\\,\\,\\, dt. \\end{array}\\\\" + newLineWithSeparation; 
     math += "\\end{array}$" + newLineWithSeparation; 
     math += "\\end{document}"; 

     // 2. Create the .tex file 
     FileWriter writer = null; 
     try { 
      writer = new FileWriter(TEMP_DIRECTORY + "\\" + TEMP_TEX_FILE_NAME + ".tex", false); 
      writer.write(math, 0, math.length()); 
      writer.close(); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } 

     // 3. Execute LaTeX from command line to generate picture 
     ProcessBuilder pb = new ProcessBuilder("pdflatex", "-shell-escape", TEMP_TEX_FILE_NAME + ".tex"); 
     pb.directory(new File(TEMP_DIRECTORY)); 
     try { 
      Process p = pb.start(); 
      StreamPrinter fluxSortie = new StreamPrinter(p.getInputStream(), false); 
      StreamPrinter fluxErreur = new StreamPrinter(p.getErrorStream(), false); 
      new Thread(fluxSortie).start(); 
      new Thread(fluxErreur).start(); 
      p.waitFor(); 
     } catch (IOException | InterruptedException ex) { 
      ex.printStackTrace(); 
     } 

     // 4. Display picture 
     JFrame maFrame = new JFrame(); 
     maFrame.setResizable(false); 
     maFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     maFrame.setSize(400, 400); 
     maFrame.getContentPane().setLayout(new FlowLayout()); 
     maFrame.getContentPane().add(new JLabel(new ImageIcon(TEMP_DIRECTORY + "\\" + TEMP_TEX_FILE_NAME + ".png"))); 
     maFrame.pack(); 
     maFrame.setVisible(true); 

     // 5. Delete files 
     for (File file : (new File(TEMP_DIRECTORY).listFiles())) { 
      if (file.getName().startsWith(TEMP_TEX_FILE_NAME + ".")) { 
       file.delete(); 
      } 
     } 
    } 
} 

Le code ci-dessus devrait créer le cadre ci-dessous: enter image description here

Nicolas