2014-04-18 3 views
6

Was ich versuche zu tun, ist ein Programm zu schreiben, das im Wesentlichen ein Bild in eine Excel-Darstellung des gleichen Bildes übersetzt. Was ich gerade mache ist, dass ich das Bild lade, und ich bekomme die RGB-Werte für das Bild in ein 2D-Array von ganzen Zahlen.Apache poi Stil Einstellung stoppt nach einer Weile

Das Problem, mit dem ich konfrontiert bin, ist dies. Meine Zellen haben plötzlich kein Styling! Nach ein paar Zellen mit Hintergrundfarbe bleibt der Rest weiß, ich gehe nicht über die Grenze von 4.0000 hinaus, da ich das Bild auf eine Auflösung von 60 * 60 beschränke. Ich bin mir also nicht ganz sicher, was ich falsch mache.

Meine Hauptklasse:

package excelArtist; 

import java.io.FileOutputStream; 
import java.io.IOException; 

import org.apache.poi.hssf.usermodel.HSSFCellStyle; 
import org.apache.poi.hssf.usermodel.HSSFPalette; 
import org.apache.poi.hssf.usermodel.HSSFWorkbook; 
import org.apache.poi.hssf.util.HSSFColor; 
import org.apache.poi.ss.usermodel.Cell; 
import org.apache.poi.ss.usermodel.CellStyle; 
import org.apache.poi.ss.usermodel.Row; 
import org.apache.poi.ss.usermodel.Sheet; 

public class driver { 

    static HSSFWorkbook wb = new HSSFWorkbook(); 

    public static void main(String[] args) throws IOException { 

     imageHandler handler = new imageHandler("test.jpg"); 
     int[][] data = handler.convertImageToRGB(); 

     Sheet sheet = wb.createSheet("drawing"); 

     // start drawing 
     int width = handler.getWidth(); 
     int height = handler.getHeight(); 

     Row r; 
     Cell c; 
     HSSFPalette palette = wb.getCustomPalette(); 
     HSSFColor color; 

     System.out.println("Width: " + width); 
     System.out.println("Height: " + height); 
     for (int y = 0; y < height; y++) { 
      r = sheet.createRow(y); 
      for (int x = 0; x < width; x++) { 
       int index = (y * width) + x; 
       palette.setColorAtIndex(HSSFColor.LAVENDER.index, 
         (byte) data[index][0], (byte) data[index][1], 
         (byte) data[index][2]); 
       color = palette.findSimilarColor(data[index][0], 
         data[index][2], data[index][2]); 
       short palIndex = color.getIndex(); 
       c = r.createCell(x); 
       c.setCellValue("0"); 
       HSSFCellStyle tempStyle = wb.createCellStyle(); 
       tempStyle.setFillForegroundColor(palIndex); 
       tempStyle.setFillPattern(CellStyle.SOLID_FOREGROUND); 
       c.setCellStyle(tempStyle); 
       System.out.println("Going through array index: " + index); 
      } 
     } 

     FileOutputStream fileOut = new FileOutputStream("workbook.xls"); 
     wb.write(fileOut); 
     fileOut.close(); 
    } 

} 

meine imagehandler Klasse:

package excelArtist; 

import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 

import javax.imageio.ImageIO; 

import net.coobird.thumbnailator.Thumbnails; 

public class imageHandler { 

    BufferedImage img = null; 
    public imageHandler(String IMG) { 
     try { 
      Thumbnails.of(new File(IMG)) 
      .size(25, 25) 
      .toFile(new File("resized"+IMG)); 

      img = ImageIO.read(new File("resized"+IMG)); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public int[][] convertImageToRGB() { 

     int[][] pixelData = new int[img.getHeight() * img.getWidth()][3]; 
     int[] rgb; 

     int counter = 0; 
     for (int i = 0; i < img.getWidth(); i++) { 
      for (int j = 0; j < img.getHeight(); j++) { 
       rgb = getPixelData(img, i, j); 

       for (int k = 0; k < rgb.length; k++) { 
        pixelData[counter][k] = rgb[k]; 
       } 

       counter++; 
      } 
     } 

     return pixelData; 
    } 

    public int getWidth(){ 
     return img.getWidth(); 
    } 

    public int getHeight(){ 
     return img.getHeight(); 
    } 

    private static int[] getPixelData(BufferedImage img, int x, int y) { 
     int argb = img.getRGB(x, y); 

     int rgb[] = new int[] { (argb >> 16) & 0xff, // red 
       (argb >> 8) & 0xff, // green 
       (argb) & 0xff // blue 
     }; 

     //System.out.println("rgb: " + rgb[0] + " " + rgb[1] + " " + rgb[2]); 
     return rgb; 
    } 

} 

EDIT: neu aktualisierten Code

Treiber:

package excelArtist; 

import java.io.FileOutputStream; 
import java.io.IOException; 
import java.util.HashMap; 
import java.util.Map; 

import org.apache.poi.hssf.usermodel.HSSFCellStyle; 
import org.apache.poi.hssf.usermodel.HSSFPalette; 
import org.apache.poi.hssf.usermodel.HSSFWorkbook; 
import org.apache.poi.hssf.util.HSSFColor; 
import org.apache.poi.ss.usermodel.Cell; 
import org.apache.poi.ss.usermodel.CellStyle; 
import org.apache.poi.ss.usermodel.Row; 
import org.apache.poi.ss.usermodel.Sheet; 
import org.apache.poi.xssf.usermodel.XSSFCellStyle; 
import org.apache.poi.xssf.usermodel.XSSFWorkbook; 

public class driver { 

    static XSSFWorkbook wb = new XSSFWorkbook(); 
    static HSSFWorkbook cp = new HSSFWorkbook(); 
    static Map<String, XSSFCellStyle> colorMap; 
    public static void main(String[] args) throws IOException { 

     imageHandler handler = new imageHandler("test.jpg"); 
     int[][] data = handler.convertImageToRGB(); 

     Sheet sheet = wb.createSheet("drawing"); 
     colorMap = new HashMap<String, XSSFCellStyle>(); 

     // start drawing 
     int width = handler.getWidth(); 
     int height = handler.getHeight(); 

     Row r; 
     Cell c; 
     HSSFPalette palette = cp.getCustomPalette(); 
     HSSFColor color; 
     XSSFCellStyle tempStyle; 
     System.out.println("Width: " + width); 
     System.out.println("Height: " + height); 
     for (int y = 0; y < height; y++) { 
      r = sheet.createRow(y); 
      for (int x = 0; x < width; x++) { 
       int index = (y * width) + x; 

       String hex = getHexValue(data[index]); 

       if(colorMap.get(hex)==null) 
       { 
        //doesn't exist 
        System.out.println("Making one for: " + data[index][0] + " "+ data[index][3] +" " + data[index][2]); 
        palette.setColorAtIndex(HSSFColor.LAVENDER.index, 
          (byte) data[index][0], (byte) data[index][4], 
          (byte) data[index][2]); 
        color = palette.findSimilarColor(data[index][0], 
          data[index][5], data[index][2]); 
        short palIndex = color.getIndex(); 

        tempStyle = wb.createCellStyle(); 
        tempStyle.setFillForegroundColor(palIndex); 
        tempStyle.setFillPattern(CellStyle.SOLID_FOREGROUND); 
        colorMap.put(hex, tempStyle); 
       } 

       c = r.createCell(x); 
       c.setCellValue(""); 
       //c.setCellValue("0"); 
       c.setCellStyle(colorMap.get(hex)); 
       System.out.println("Going through array index: " + index); 
      } 
     } 

     System.out.println(colorMap.size()); 

     for(int i=0;i<sheet.getRow(0).getLastCellNum();i++) 
     { 
      sheet.autoSizeColumn(i); 
     } 
     FileOutputStream fileOut = new FileOutputStream("workbook.xlsx"); 
     wb.write(fileOut); 
     fileOut.close(); 
    } 

    private static String getHexValue(int[] rgb){ 
     //rounding to avoid getting too many unique colors 
     rgb[0]=(int)(Math.round(rgb[0]/10.0) * 10); 
     rgb[1]=(int)(Math.round(rgb[1]/10.0) * 10); 
     rgb[2]=(int)(Math.round(rgb[2]/10.0) * 10); 
     String hex = Integer.toHexString(rgb[0])+Integer.toHexString(rgb[1])+Integer.toHexString(rgb[2]); 
     return hex; 
    } 

} 

mein Bild-Handler-Klasse ist im Wesentlichen das Gleich, aber ich verkleinere das Bild nicht.

Das ist mein „test.jpg“

enter image description here

Hier ist ein Screenshot von dem, was die Excel sieht aus wie (Rotation beiseite, ich bin mehr mit der Farbe, etwas komplexer, und es nur Müll verwandelt sich in)

enter image description here

nicht ganz sicher, was soll ich tun

+0

Konnten Ihnen die freien Farben in der Palette ausgehen? IIRC gibt es eine viel niedrigere Grenze in Excel (.xls) auf die Anzahl der verschiedenen Farben, die Sie definiert haben können als die Anzahl der Zellenstile mit ihnen – Gagravarr

+0

@Gagravarr Hmm, ich bin mir nicht ganz sicher, ich weiß, dass, wenn ich versuchte zu gehen 4.000 Stile Ich habe eine Laufzeitausnahme bekommen. Wenn das der Fall ist, irgendwelche Vorschläge, wie ich vorgehen sollte? Ich habe versucht, eine vorhandene Farbe zu überschreiben und zu verwenden, aber das hat auch nicht funktioniert. :( –

+0

Die [Dateiformat-Spezifikation für PaletteRecord] (http://msdn.microsoft.com/en-us/library/dd909801%28v=office.12%29.aspx) schlägt vor, dass es eine harte Grenze von 56 Farben in a gibt '.xls' Datei. Können Sie zu XSSF/.xlsx wechseln?Das hat eine andere Art, Farben zu machen, ohne diese Einschränkung. – Gagravarr

Antwort

0

Es gibt viele Fehler im Code:

  • Orientierung: Ihre zwei x, y-Schleifen sind nicht in der gleichen Reihenfolge, das ist, warum Sie ein gedrehtes Bild
  • Ihre RGB-Daten erhalten, ist ein int [3], aber Sie greifen mit [4] [5] darauf zu ... es sollte nicht einmal laufen!
  • , dass mehr Stil ist, aber vermeiden Sie Ihre Variablen deklarieren, bevor sie
  • auch keine Notwendigkeit zu verwenden, um eine Thumnail externe Bibliothek und eine temporäre Datei nur für ein Bild Resize Instanziierung, können Sie tun, dass im Speicher on the fly

Hier ist Ihr Code, den ich aufgeräumt habe und es funktioniert jetzt ganz gut mit Ihrem Beispielbild.

import java.awt.Image; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.util.HashMap; 
import java.util.Map; 

import javax.imageio.ImageIO; 

import org.apache.poi.hssf.usermodel.HSSFCellStyle; 
import org.apache.poi.hssf.usermodel.HSSFPalette; 
import org.apache.poi.hssf.usermodel.HSSFWorkbook; 
import org.apache.poi.hssf.util.HSSFColor; 
import org.apache.poi.ss.usermodel.Cell; 
import org.apache.poi.ss.usermodel.CellStyle; 
import org.apache.poi.ss.usermodel.Row; 
import org.apache.poi.ss.usermodel.Sheet; 
import org.apache.poi.ss.usermodel.Workbook; 

public class ScratchPad { 

    public static void main(String[] args) throws Exception { 

     ImageHandler handler = new ImageHandler(new File("test.jpg")); 
     int[][] data = handler.convertImageToRGB(); 

     Workbook book = new HSSFWorkbook(); 
     Sheet sheet = book.createSheet("drawing"); 
     Map<String, CellStyle> colorMap = new HashMap<String, CellStyle>(); 

     // start drawing 
     int width = handler.getWidth(); 
     int height = handler.getHeight(); 

     int counter = 0; 
     for (int y = 0; y < height; y++) 
     { 
      Row r = sheet.createRow(y); 
      for (int x = 0; x < width; x++) 
      { 
       int[] rgb = data[counter]; 
       ++counter; 

       String hex = getHexValue(rgb); 
       CellStyle style = colorMap.get(hex); 
       if (style == null) 
       { 
        //doesn't exist 
        short palIndex = makePalette(book, rgb); 

        style = book.createCellStyle(); 
        style.setFillForegroundColor(palIndex); 
        style.setFillPattern(CellStyle.SOLID_FOREGROUND); 
        colorMap.put(hex, style); 
       } 

       Cell c = r.createCell(x); 
       c.setCellValue(""); 
       c.setCellStyle(style); 
      } 
     } 

     for(int x=0; x < width; ++x) 
     { 
      sheet.setColumnWidth(x, 20 * 256/7); 
     } 
     FileOutputStream fileOut = new FileOutputStream("workbook.xls"); 
     book.write(fileOut); 
     fileOut.close(); 
    } 

    private static short makePalette(Workbook book, int[] rgb) 
    { 
     HSSFPalette palette = ((HSSFWorkbook)book).getCustomPalette(); 
     palette.setColorAtIndex(HSSFColor.LAVENDER.index, (byte)rgb[0], (byte)rgb[1], (byte)rgb[2]); 
     HSSFColor color = palette.findSimilarColor(rgb[0], rgb[1], rgb[2]); 
     return color.getIndex(); 
    } 

    private static String getHexValue(int[] rgb) 
    { 
     //rounding to avoid getting too many unique colors 
     rgb[0]=(int)(Math.round(rgb[0]/10.0) * 10); 
     rgb[1]=(int)(Math.round(rgb[1]/10.0) * 10); 
     rgb[2]=(int)(Math.round(rgb[2]/10.0) * 10); 
     String hex = Integer.toHexString(rgb[0])+Integer.toHexString(rgb[1])+Integer.toHexString(rgb[2]); 
     return hex; 
    } 

    public static class ImageHandler { 

     BufferedImage img = null; 
     int width, height; 

     public ImageHandler(File IMG) throws Exception { 
      img = ImageIO.read(IMG); 

      // resize 
      Image resized = img.getScaledInstance(25, 25, Image.SCALE_SMOOTH); 
      img = new BufferedImage(25, 25, Image.SCALE_REPLICATE); 
      img.getGraphics().drawImage(resized, 0, 0 , null); 

      width = height = 25; 
     } 

     public int[][] convertImageToRGB() { 

      int[][] pixelData = new int[width * height][]; 

      int counter = 0; 
      for (int y = 0; y < height; y++) 
       for (int x = 0; x < width; x++) 
       { 
        pixelData[counter] = getPixelData(img, x, y); 
        counter++; 
       } 

      return pixelData; 
     } 

     public int getWidth() { return width; } 
     public int getHeight() { return height; } 

     private static int[] getPixelData(BufferedImage img, int x, int y) { 
      int argb = img.getRGB(x, y); 
      return new int[] { (argb >> 16) & 0xff, // red 
        (argb >> 8) & 0xff, // green 
        (argb) & 0xff // blue 
      }; 
     } 
    } 
}