2010-08-18 4 views
0

Désolé pour mon mauvais anglais. J'espère que vous comprendrez mon problème. J'ai une question sur le développement de hadoop.hadoop inputFile en tant que BufferedImage

Je dois me former sur un simple projet de traitement d'image utilisant hadoop. Tout ce que je veux faire est de faire pivoter une image avec Hadoop (bien sûr, je ne veux pas que hadoop utilise toute l'image). J'ai un problème avec inputFormat. que devrais-je faire?

les solutions que j'ai trouvés:

  • mettre un SequenceFile comme inputFormat (? Mais, je dois faire une première map/reduce travail, puis un autre pour faire la rotation)
  • étend FileInputFormat et RecordReader avec une classe j'ai développé: ImageWritable. Il contient une image bufferedImage (l'image originale), un bufferedImage [] qui est l'image divisée par un nombre quelconque, et un int [] pixelsArray, qui est la "sérialisation" de l'image.

Je ne suis pas très familier avec les génériques en Java, donc je Prolonge les classes comme ça:

public class ImageInputFormat extends FileInputFormat< IntWritable, ImageWritable> 
public class ImageRecordReader extends RecordReader< IntWritable, ImageWritable> 

est-il exact? En fait, je suis une perdue dans cette jungle, et je ne sais même pas quoi faire/utiliser après. Je lis beaucoup de papier sur hadoop, mais je ne comprends toujours pas comment fonctionne map/reduce avec le fichier input. Y a-t-il quelqu'un ici pour m'aider s'il vous plait?

remercient

Répondre

0

je cherchais une aide pendant deux semaines, mais cet après-midi, je l'ai trouvé une page intersting: http://wiki.apache.org/hadoop/HadoopMapReduce?highlight=(inputf)

ainsi, j'explorais le deuxième point. Maintenant, je peux atteindre le recordReader sans erreur. J'ai regardé la source de code source de classe. ça m'aide vraiment. ici est une partie de ImageRecordReader

final class ImageRecordReader extends RecordReader<IntWritable, ImageWritable>{ 

    ImageWritable iwri; 
    IntWritable key; 


    public ImageRecordReader(TaskAttemptContext context, FileSplit fileSplit) throws IOException, InterruptedException { 
     System.out.println(fileSplit.getPath().toString()); 
     key = new IntWritable(0); 
     iwri = new ImageWritable(4); 
    } 

    @Override 
    public void initialize(InputSplit split, TaskAttemptContext context) throws IOException, InterruptedException { 
     FileSplit fsplit = (FileSplit) split; 
     iwri.CreateImageWritableFromSerial(fsplit.getPath()); 
     iwri.affiche(); 
    } 

et ici le code principal pour faire le BufferedImage devenir inscriptibles:

public final class ImageWritable implements Writable{ 

    private BufferedImage bi; 
    private int[] pixelsArray; 
    private BufferedImage[] biPart; 
    private int nbPart; 

    public int[] getPixelsArray(){return pixelsArray;} 

    private void setPixelArray(){ 
     int width = bi.getWidth(); 
     int height = bi.getHeight(); 
     pixelsArray = new int[width * height +2]; 
     Image im = bi; 
     PixelGrabber pg = new PixelGrabber(im, 0, 0, width, height, pixelsArray, 2, width); 
     try{ pg.grabPixels(); } 
     catch(InterruptedException ex){ ex.printStackTrace(); } 
     pixelsArray[0] = width; 
     pixelsArray[1] = height; 
    } 
    public int[] getPixelArray(Image im){ 
     int width = im.getWidth(null); 
     int height = im.getHeight(null); 

     pixelsArray = new int[width * height +2]; 

     PixelGrabber pg = new PixelGrabber(im, 0, 0, width, height, pixelsArray, 2, width); 
     try{ pg.grabPixels(); } 
     catch(InterruptedException ex) { ex.printStackTrace(); } 

     pixelsArray[0] = width; 
     pixelsArray[1] = height; 
     System.out.println("Width = "+ width); 
     System.out.println("Heitgh = "+ height); 
     return pixelsArray; 
    } 

    private void createPartfromPixelArray(int[] pixArr){ 
     MemoryImageSource mis; 
     Toolkit tk = Toolkit.getDefaultToolkit(); 
     int wPart = pixArr[0]/(nbPart/2); 
     int hPart = pixArr[1]/2; 
     int lgLi = pixArr[0]; 
     for(int i = 1; i <= nbPart; ++i){ 
      if(i<=nbPart/2){ 
       mis = new MemoryImageSource(wPart, hPart, pixArr, 2+ i*wPart, lgLi); 
      } else { 
       mis = new MemoryImageSource(wPart, hPart, pixArr, (pixArr.length+2)/2 + (i%(nbPart/2))*wPart, lgLi); 
      } 

      biPart[i-1] = RotationToolKit.getBuffered(tk.createImage(mis)); 
      affiche(biPart[i-1], Integer.toString(i)); 
     } 

    } 

    public ImageWritable(int nbPart){ 
     this.nbPart = nbPart; 
     bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); 
     biPart = new BufferedImage[this.nbPart]; 
    } 
    public boolean CreateImageWritableFromSerial(Path path){ 
     try { 
      System.out.println(path.toString()); 
      DataInput dataInput = new FileImageInputStream(new File(path.toString().substring(5))); 
      readFields(dataInput); 
      return true; 
     } catch (FileNotFoundException ex) { 
      Logger.getLogger(ImageWritable.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (IOException ex) { 
      Logger.getLogger(ImageWritable.class.getName()).log(Level.SEVERE, null, ex); 
     } 
      return false; 
    } 


    public void write(DataOutput d) throws IOException { 
     System.out.println("Width du tableau = "+ pixelsArray[0]); 
     System.out.println("Heitgh du tableau = "+ pixelsArray[1]); 
     System.out.println("length du tableau = "+ pixelsArray.length); 
     for(int o : pixelsArray){ 
      d.writeInt(o); 
     } 
     System.out.println(); 
    } 

    public void readFields(DataInput di) throws IOException { 
     int w = di.readInt(); 
     int h = di.readInt(); 
     int length = w * h; 
     System.out.println("Width lue du tableau = "+ w); 
     System.out.println("Heitgh lue du tableau = "+ h); 
     System.out.println("length calculée du tableau = "+ length); 
     pixelsArray = new int[length+2]; 
     pixelsArray[0] = w; 
     pixelsArray[1] = h; 
     for(int i = 2; i<pixelsArray.length; i++) 
      pixelsArray[i] = di.readInt(); 

     System.out.println(); 

     createPartfromPixelArray(pixelsArray); 
     bi = createfromPixelsArray(pixelsArray); 
    } 

    public ImageWritable getPart(int i){ return new ImageWritable(biPart[i]); } 
    public BufferedImage getBi() { return bi; } 
    public void setWithoutCreateNewBi(BufferedImage bi){ this.bi = bi; } 
    public void setBi(BufferedImage bi) { 
     Graphics2D g = bi.createGraphics(); 
     g.setComposite(AlphaComposite.DstIn); 
     g.drawImage(this.bi, null, null); 
     g.dispose(); 
    } 

    public int getNbPart() {return nbPart; } 
    public void setNbPart(int part) { nbPart = part; } 

} 

Les problèmes restants sont les suivants: * Je ne sais pas vraiment si elle est toujours correcte * comment diviser suffisamment l'image pour avoir une petite image de la taille du bloc hdfs?

merci pour les personnes qui pourraient m'aider.