Search code examples
image-processinghadoopsequencefile

How to Convert SequenceFile in Hadoop to Image file? Following code returns error (bImageFromConvert is NULL)


import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import javax.imageio.ImageIO;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.util.ReflectionUtils;



public class SeqToImage {

/* Converting a sequence file to Image Sequence file being used is the one generated from an image; .png format */

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

        Configuration confHadoop = new Configuration();       
        FileSystem fs = FileSystem.get(confHadoop);
        Path inPath = new Path("/home/Desktop/1.seq");
        SequenceFile.Reader reader = new SequenceFile.Reader(fs, inPath, confHadoop);
        Writable key = (Writable)
        ReflectionUtils.newInstance(reader.getKeyClass(), confHadoop);
        Writable value = (Writable)
        ReflectionUtils.newInstance(reader.getValueClass(), confHadoop);
        reader.next(key,value);

// Key of sequence file is image name and value is image content.

  System.out.println("KEY "+key.toString());
            byte[] b = Bytes.toBytes(value.toString());
            System.out.println(b.length);

// Output is some number of bytes, which means b is NOT NULL

BufferedImage bImageFromConvert = ImageIO.read(new ByteArrayInputStream(b));

// Following line returns error since bImageFromConvert is NULL

System.out.println((bImageFromConvert.toString()).length());
        ImageIO.write(bImageFromConvert, "png", new File(
                "/home/Desktop/imageAgain.png"));
        }
    }

Solution

  • Your value(image) should by BytesWritable. YOu should cast like :

         BytesWritable value = (BytesWritable)
        ReflectionUtils.newInstance(reader.getValueClass(), confHadoop);
    

    Second instead of Bytes.toBytes you should use copyBytes()

    It give a copy of the bytes that is exactly the length of the data. So This should work

        Configuration confHadoop = new Configuration();       
        FileSystem fs = FileSystem.get(confHadoop);
        Path inPath = new Path("/home/Desktop/1.seq");
        SequenceFile.Reader reader = new SequenceFile.Reader(fs, inPath, confHadoop);
        //Name of your Image
        Text key = (Text)
        ReflectionUtils.newInstance(reader.getKeyClass(), confHadoop);
        // Value -- mage
        BytesWritable value = (BytesWritable)
        ReflectionUtils.newInstance(reader.getValueClass(), confHadoop);
        reader.next(key,value);
        .......
                    byte[] b = copyBytes(value) ;
    
        System.out.println((bImageFromConvert.toString()).length());
        ImageIO.write(bImageFromConvert, "png", new File(
                "/home/Desktop/imageAgain.png"));
        }
    }
    

    That will do