Using readObject to get byte[][] giving OptionalDataException - java

I have a slight problem reading some files I have made. I am making a game and have decided to make my own file type for the maps. I have made a special application to make these map files. Once I instantiate a map I can choose to call readFile(String path) to set the map as the one saved. I know that I have to read and write the stream in the same order and everything went well until I added the statements about reading and writing the byte[][]. I cannot figure out why I am getting this exception and how to still read a byte[][]. Here is my class.
public class Map implements Serializable{
String savePath;
int boxWidth;
int boxHeight;
int mapWidth;
int mapHeight;
BufferedImage map;
byte[][] encoded;
LinkedList<BufferedImage> tileSet = new LinkedList<BufferedImage>();
Map(int boxWidth, int boxHeight, int mapWidth, int mapHeight){
map = new BufferedImage(boxWidth * mapWidth, boxHeight * mapHeight, BufferedImage.TYPE_INT_RGB);
Graphics g = map.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, map.getWidth(), map.getHeight());
g.dispose();
this.boxHeight = boxHeight;
this.boxWidth = boxWidth;
this.mapHeight = mapHeight;
this.mapWidth = mapWidth;
initEncode();
}
Map(){
map = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
this.boxHeight = 0;
this.boxWidth = 0;
this.mapHeight = 0;
this.mapWidth = 0;
initEncode();
}
void initEncode(){
int width = 2 * mapWidth + 1;
int height = 2 * mapHeight + 1;
encoded = new byte[width][height];
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
encoded[i][j] = 0;
}
}
}
void setMapTile(int i, int j, byte index){
encoded[2 * i + 1][2 * j + 1] = index;
}
void setMapWall(int i, int j, byte index){
encoded[2 * i][2 * i] = index;
}
void addToTileset(Tile tile){
tileSet.add(tile.tile);
writeFile(savePath);
}
//writing to file with path - boolean is for whether it went successfully or not
boolean writeFile(String path){
savePath = path;
try{
OutputStream file = new FileOutputStream(path);
OutputStream buffer = new BufferedOutputStream(file);
ObjectOutputStream output = new ObjectOutputStream(buffer);
writeObject(output);
output.close();
buffer.close();
file.close();
}catch(IOException ex){
System.err.println("Could not Write to file: " + path + "\nError caused by: " + ex);
return false;
}
return true;
}
//reading from file with path - boolean is for whether it went successfully or not
boolean readFile(String path){
savePath = path;
try{
InputStream file = new FileInputStream(path);
InputStream buffer = new BufferedInputStream(file);
ObjectInputStream in = new ObjectInputStream(buffer);
readObject(in);
initEncode();
file.close();
buffer.close();
in.close();
}catch(IOException ex){
System.err.println("Could not read from file: " + path + "\nError caused by: " + ex + "\n");
ex.printStackTrace();
return false;
}catch(ClassNotFoundException e){
System.err.println("Could not read from file: " + path + "\nError caused by: " + e + "\n");
e.printStackTrace();
}
return true;
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.writeInt(boxHeight);
out.writeInt(boxWidth);
out.writeInt(mapHeight);
out.writeInt(mapWidth);
ImageIO.write(map, "png", out);
out.writeObject(encoded);
out.writeInt(tileSet.size());
for(BufferedImage b: tileSet){
ImageIO.write(b, "png", out);
}
}
public void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
boxHeight = in.readInt();
boxWidth = in.readInt();
mapHeight = in.readInt();
mapWidth = in.readInt();
map = ImageIO.read(in);
encoded = (byte[][]) in.readObject();
int tileSetSize = in.readInt();
for(int i = 0; i < tileSetSize; i++){
tileSet.add(ImageIO.read(in));
}
}
}
Is there some reason that my (byte[][]) readObject() line is throwing OptionalDataException and how do i still read/write my byte[][].
EDIT: Thank you for your answer Abhinav Kumar. I overlooked that but when I fixed the code it still gave me the same error on the same line. (The class has been fixed now).

You have to read the InputStream in the same order and same format which you write in the stream otherwise you would get OptionalDataException
You have written the data in OutputStream in the order :-
ImageIO.write(map, "png", out);
out.writeInt(2 * mapWidth + 1);
out.writeObject(encoded);
And you are reading the stream in the order :-
map = ImageIO.read(in);
encoded = (byte[][]) in.readObject();
Just read the int after u read map.The correct code would be :-
public void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
boxHeight = in.readInt();
boxWidth = in.readInt();
mapHeight = in.readInt();
mapWidth = in.readInt();
map = ImageIO.read(in);
in.readInt();// you read this int and assign it to the object as you wish
encoded = (byte[][]) in.readObject();
int tileSetSize = in.readInt();
for(int i = 0; i < tileSetSize; i++){
tileSet.add(ImageIO.read(in));
}
}

Related

How to read the large text files efficiently in java

Here, I am reading the 18 MB file and store it in a two dimensional array. But this program takes almost 15 minutes to run. Is there anyway to optimize the running time of the program. The file contains only binary values. Thanks in advanceā€¦
public class test
{
public static void main(String[] args) throws FileNotFoundException, IOException
{
BufferedReader br;
FileReader fr=null;
int m = 2160;
int n = 4320;
int[][] lof = new int[n][m];
String filename = "D:/New Folder/ETOPOCHAR";
try {
Scanner input = new Scanner(new File("D:/New Folder/ETOPOCHAR"));
double range_km=1.0;
double alonn=-57.07; //180 to 180
double alat=38.53;
while (input.hasNextLine()) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
try
{
lof[j][i] = input.nextInt();
System.out.println("value[" + j + "][" + i + "] = "+ lof[j][i]);
}
catch (java.util.NoSuchElementException e) {
// e.printStackTrace();
}
}
} //print the input matrix
}
I have also tried with byte array but i can not save it in twoD array...
public class FileToArrayOfBytes
{
public static void main( String[] args )
{
FileInputStream fileInputStream=null;
File file = new File("name of file");
byte[] bFile = new byte[(int) file.length()];
try {
//convert file into array of bytes
fileInputStream = new FileInputStream(file);
fileInputStream.read(bFile);
fileInputStream.close();
for (int i = 0; i < bFile.length; i++) {
System.out.print((char)bFile[i]);
}
System.out.println("Done");
}catch(Exception e){
e.printStackTrace();
}
}
}
You can read the file into a byte array first, then deserialize these bytes. Start with 2048 bytes buffer (as input buffer), then experiment by increasing/decreasing its size, but the experimental buffer size values should be a power of two (512, 1024, 2048, etc).
As far as I rememenber, there are good chances that the best performance can be achived with a buffer of size 2048 bytes, but it is OS dependent and should be verified.
Code sample (here you can try different values of BUFFER_SIZE variable, in my case I've read a test file of size 7.5M in less then one second):
public static void main(String... args) throws IOException {
File f = new File(args[0]);
byte[] buffer = new byte[BUFFER_SIZE];
ByteBuffer result = ByteBuffer.allocateDirect((int) f.length());
try (FileInputStream fos = new FileInputStream(f)) {
int bytesRead;
int totalBytesRead = 0;
while ((bytesRead = fos.read(buffer, 0, BUFFER_SIZE)) != -1) {
result.put(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
}
// debug info
System.out.printf("Read %d bytes\n", totalBytesRead);
// Here you can do whatever you want with the result, including creation of a 2D array...
int pos = result.position();
result.rewind();
for (int i = 0; i < pos / 4; i++) {
System.out.println(result.getInt());
}
}
}
Take your time and read docs for java.io, java.nio packages as well as Scanner class, just to improve understanding.

How do I copy an array?

What I'm trying to do is I'm trying to take an image and make it a tiled image. The starting image should look like this.
http://i1146.photobucket.com/albums/o525/walroid/letter_Q_grayscale_zpsd3b567a7.jpg
And then what the image is turned into tiles then it should look like this:
http://i1146.photobucket.com/albums/o525/walroid/replicate_example_zps5e5248e8.jpg
In my code the pictures are saved into an array which is called into the method. What I want to do is copy that array and then put it into another array which will replicate the image. How do I do that?
Here's my entire code:
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
public class ImageProcessor {
public static void main(String[] args) {
if (args.length < 3) {
System.out.println("Not enough arguments");
System.exit(-1);
}
String function = args[0];
if (function.equals("-reflectV")) {
String inputFileName = args[1];
String outputFileName = args[2];
int[][] imageArr = readGrayscaleImage(inputFileName);
int[][] reflectedArr = reflectV(imageArr);
writeGrayscaleImage(outputFileName, reflectedArr);
} else if (function.equals("-reflectH")) {
String inputFileName = args[1];
String outputFileName = args[2];
int[][] imageArr = readGrayscaleImage(inputFileName);
int[][] reflectedArr = reflectH(imageArr);
writeGrayscaleImage(outputFileName, reflectedArr);
} else if (function.equals("-ascii")) {
String inputFileName = args[1];
String outputFileName = args[2];
int[][] imageArr = readGrayscaleImage(inputFileName);
int[][] reflectedArr = reflectV(imageArr);
try {
PrintStream output = new PrintStream(new File("output.txt"));
} catch (java.io.FileNotFoundException ex) {
System.out.println("Error: File Not Found");
System.exit(-1);
}
} else if (function.equals("-adjustBrightness")) {
String amount = args[1];
int a = Integer.parseInt(amount);
System.out.print(a)
String inputFileName = args[1];
String outputFileName = args[2];
int[][] imageArr = readGrayscaleImage(inputFileName);
int[][] brightnessArr = adjustBrightness(imageArr);
writeGrayscaleImage(outputFileName, brightnessArr);
} else
System.out.println("That is not a valid choice");
system.exit(-1)
public static int[][] reflectV ( int[][] arr){
int[][] reflected = new int[arr.length][arr[0].length];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
reflected[i][j] = arr[i][arr[i].length - 1 - j];
}
}
return reflected;
}
public static int[][] reflectH ( int[][] arr){
int[][] reflected = new int[arr.length][arr[0].length];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
reflected[j][i] = arr[i][arr[j].length - 1 - j];
}
}
return reflected;
}
public static int[][] adjustBrightness ( int[][] arr){
int[][] brightness = new int[arr.length][arr[0].length];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
RGB
}
}
return brightness;
}
public static int[][] readGrayscaleImage (String filename){
int[][] result = null; //create the array
try {
File imageFile = new File(filename); //create the file
BufferedImage image = ImageIO.read(imageFile);
int height = image.getHeight();
int width = image.getWidth();
result = new int[height][width]; //read each pixel value
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int rgb = image.getRGB(x, y);
result[y][x] = rgb & 0xff;
}
}
} catch (IOException ioe) {
System.err.println("Problems reading file named " + filename);
System.exit(-1);
}
return result;
}
public static void writeGrayscaleImage(String filename, int[][] array) {
int width = array[0].length;
int height = array.length;
try {
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB); //create the image
//set all its pixel values based on values in the input array
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int rgb = array[y][x];
rgb |= rgb << 8;
rgb |= rgb << 16;
image.setRGB(x, y, rgb);
}
}
//write the image to a file
File imageFile = new File(filename);
ImageIO.write(image, "jpg", imageFile);
} catch (IOException ioe) {
System.err.println("Problems writing file named " + filename);
System.exit(-1);
}
}
}
You need to do a "deep copy" of the array. Simply copying your array to a new variable will only assign the reference (shallow copy), and if you manipulate data in one of the arrays, it will change both.
Shallow Copy:
String[] myArray2 = myArray1;
This will essentially have 2 references pointing at the same data. If you change anything in myArray2, it will also change in myArray1.
Deep Copy:
There are multiple ways to do a deep copy. The obvious way is to iterate over your array and copy each element one at a time into the new array.
String[] myArray2 = new String[myArray1.length];
for (int i = 0; i < myArray1.length; i++) {
myArray2[i] = myArray1[i];
}
A sometimes simpler/faster way is to serialize your array and then de-serialize it while it's still in memory. This causes the JVM to treat the de-serialized array as an entirely new array ("no strings attached" so-to-speak).
Here's an example from an old project of mine:
/**
* Clones an object creating a brand new
* object by value of input object. Accomplishes this
* by serializing the object, then deservializing it.
*
* #param obj Input Object to clone
* #return a new List<Product> type cloned from original.
* #throws IOException If IOException
* #throws ClassNotFoundException If ClassNotFoundException
*/
private static List<Product> cloneProdList(Object obj) throws IOException, ClassNotFoundException {
java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
java.io.ObjectOutputStream obj_out = new java.io.ObjectOutputStream(bos);
obj_out.writeObject(obj);
java.io.ByteArrayInputStream bis = new java.io.ByteArrayInputStream(bos.toByteArray());
java.io.ObjectInputStream obj_in = new java.io.ObjectInputStream(bis);
#SuppressWarnings("unchecked")
List<Product> newObj = (List<Product>)obj_in.readObject();
bos.close();
bis.close();
obj_out.close();
obj_in.close();
return newObj;
}
This code takes a List type as the input (well, it actually casts to an Object type), serializes and then de-serializes while still in memory, then casts back into a List object and returns the new object back out of the method.
You can modify it to use an Array object instead pretty easily. (an array[] type will autobox into Array for you)
https://docs.oracle.com/javase/7/docs/api/java/lang/System.html#arraycopy%28java.lang.Object,%20int,%20java.lang.Object,%20int,%20int%29
You can use System.arraycopy in a for loop to copy from one array to other.
Using the Array class and calling the static method Array.copyOf(array, array.length) is quite handy so that if myArray1 is the previous array and myArray2 is the new array then myArray2 = Array.copyOf(myArray1, myArray1.length)

Error in my mp3 splitter program?

So, I made a program that splits a .mp3 file in Java. Basically, it works fine on some files but on some, the first split file encounters an error after playing some part. The other files work completely fine though.
I think it has something to do with how a file cannot be a multiple of the size of my array and there should be some mod value left. Can anybody please identify the error in this code and correct it?
(here, splitval = no. of splits to be made, filename1= the selected file)
int splitsize=filesize/splitval;
String filecalled;
try
{
byte []b=new byte[splitsize];
FileInputStream fis = new FileInputStream(filename1);
name1=filename2.replaceAll(".mp3", "");
for(int j=1;j<=splitval;j++)
{
filecalled=name1+"_split_"+j+".mp3";
FileOutputStream fos = new FileOutputStream(filecalled);
int i=fis.read(b);
fos.write(b, 0, i);
//System.out.println("no catch");
}
JOptionPane.showMessageDialog(this, "split process successful");
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
Thanks in advance!
EDIT:
I edited the code as suggested, ran it. Here:
C:\Users\dell5050\Desktop\Julien.mp3 5383930 bytes
C:\Users\dell5050\Desktop\ Julien_split_1.mp3 1345984 bytes
C:\Users\dell5050\Desktop\ Julien_split_2.mp3 1345984 bytes
C:\Users\dell5050\Desktop\ Julien_split_3.mp3 1345984 bytes
C:\Users\dell5050\Desktop\ Julien_split_4.mp3 1345978 bytes
There is change in the last few bytes which means that the filesize%splitval is solved.. but still the first file in this.. containing '_split_1' has error while playing some of the last part.
The second file containing '_split_2' starts exactly where the first ended. So the split process is correct. Then, what exactly is the extra empty in the end of the first file?
Also, I noticed that the artwork and info of the original file carries over into the first file ONLY. No other files. Does it have something to do with that? Same thing doesnt happen in some other mp3 files.
CODE:
FileInputStream fis;
FileOutputStream fos;
int splitsize = (int)(filesize / splitval) + (int)(filesize % splitval);
byte[] b = new byte[splitsize];
System.out.println(filename1 + " " + filesize + " bytes");
try
{
fis = new FileInputStream(file);
name1 = filename2.replaceAll(".mp3", "");
for (int j = 1; j <= splitval; j++)
{
String filecalled = name1 + "_split_" + j + ".mp3";
fos = new FileOutputStream(filecalled);
int i = fis.read(b);
fos.write(b, 0, i);
fos.close();
System.out.println(filecalled + " " + i + " bytes");
}
}
catch(IOException ie)
{
System.out.println(ie.getMessage());
}
I doubt you could split a mp3 file just by copying n-bytes to a file and go to the next. Mp3 has a specific format and you'll probably need a library to handle this format.
EDIT regarding the size of the part files being all equal:
You are not writing all the bytes of the file to the split files. If you sum the sizes of all split files and compare it to the size of the original file you'll find out that your missing some bytes. This is because your loop runs from 1 to splitval and always writes the exact number of bytes to each part file i.e. splitsize. So the number of bytes your are missing is filesize % splitval.
To resolve this problem simply add filesize % splitval to splitsize. This way you'll not be missing any bytes. The files from 1 to splitval - 1 will have the same size, the last file will be smaller.
Here is a corrected version of your code with some additions to merge the split files in order to perform an assertion using SHA1-checksum.
Disclaimer - The output files are not expected to be proper mp3 files
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import junit.framework.Assert;
import org.junit.Test;
public class SplitFile {
#Test
public void splitFile() throws IOException, NoSuchAlgorithmException {
String filename1 = "mp3/Innocence_-_Nero.mp3";
File file = new File(filename1);
FileInputStream fis = null;
FileOutputStream fos = null;
long filesize = file.length();
long filesizeActual = 0L;
int splitval = 5;
int splitsize = (int)(filesize / splitval) + (int)(filesize % splitval);
byte[] b = new byte[splitsize];
System.out.println(filename1 + " " + filesize + " bytes");
try {
fis = new FileInputStream(file);
String name1 = filename1.replaceAll(".mp3", "");
String mergeFile = name1 + "_merge.mp3";
for (int j = 1; j <= splitval; j++) {
String filecalled = name1 + "_split_" + j + ".mp3";
fos = new FileOutputStream(filecalled);
int i = fis.read(b);
fos.write(b, 0, i);
fos.close();
fos = null;
System.out.println(filecalled + " " + i + " bytes");
filesizeActual += i;
}
Assert.assertEquals(filesize, filesizeActual);
mergeFileParts(filename1, splitval);
check(filename1, mergeFile);
} finally {
if(fis != null) {
fis.close();
}
if(fos != null) {
fos.close();
}
}
}
private void mergeFileParts(String filename1, int splitval) throws IOException {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
String name1 = filename1.replaceAll(".mp3", "");
String mergeFile = name1 + "_merge.mp3";
fos = new FileOutputStream(mergeFile);
for (int j = 1; j <= splitval; j++) {
String filecalled = name1 + "_split_" + j + ".mp3";
File partFile = new File(filecalled);
fis = new FileInputStream(partFile);
int partFilesize = (int) partFile.length();
byte[] b = new byte[partFilesize];
int i = fis.read(b, 0, partFilesize);
fos.write(b, 0, i);
fis.close();
fis = null;
}
} finally {
if(fis != null) {
fis.close();
}
if(fos != null) {
fos.close();
}
}
}
private void check(String expectedPath, String actualPath) throws IOException, NoSuchAlgorithmException {
System.out.println("check...");
FileInputStream fis = null;
try {
File expectedFile = new File(expectedPath);
long expectedSize = expectedFile.length();
File actualFile = new File(actualPath);
long actualSize = actualFile.length();
System.out.println("exp=" + expectedSize);
System.out.println("act=" + actualSize);
Assert.assertEquals(expectedSize, actualSize);
fis = new FileInputStream(expectedFile);
String expected = makeMessageDigest(fis);
fis.close();
fis = null;
fis = new FileInputStream(actualFile);
String actual = makeMessageDigest(fis);
fis.close();
fis = null;
System.out.println("exp=" + expected);
System.out.println("act=" + actual);
Assert.assertEquals(expected, actual);
} finally {
if(fis != null) {
fis.close();
}
}
}
public String makeMessageDigest(InputStream is) throws NoSuchAlgorithmException, IOException {
byte[] data = new byte[1024];
MessageDigest md = MessageDigest.getInstance("SHA1");
int bytesRead = 0;
while(-1 != (bytesRead = is.read(data, 0, 1024))) {
md.update(data, 0, bytesRead);
}
return toHexString(md.digest());
}
private String toHexString(byte[] digest) {
StringBuffer sha1HexString = new StringBuffer();
for(int i = 0; i < digest.length; i++) {
sha1HexString.append(String.format("%1$02x", Byte.valueOf(digest[i])));
}
return sha1HexString.toString();
}
}
Output (for my test file)
mp3/Innocence_-_Nero.mp3 5048528 bytes
mp3/Innocence_-_Nero_split_1.mp3 1009708 bytes
mp3/Innocence_-_Nero_split_2.mp3 1009708 bytes
mp3/Innocence_-_Nero_split_3.mp3 1009708 bytes
mp3/Innocence_-_Nero_split_4.mp3 1009708 bytes
mp3/Innocence_-_Nero_split_5.mp3 1009696 bytes
check...
exp=5048528
act=5048528
exp=e81cf2dc65ab84e3df328e52d63a55301232b917
act=e81cf2dc65ab84e3df328e52d63a55301232b917

File transfer over socket using JAVA

I was searching a code in java for sending multiple files over a socket, I found this code which consists of a TX main, a RX main and a class for all the dirty work I assume. Code runs with no errors but I have a questions for the experts,
where exactly in the code, the user types the files that he/she want to send to the server ?
And in the server main, what is the location where the server stores the received file, and with what name ?
Where exactly in this code ( TX / RX / ByteStream), should I amend to specify what file goes in ?
I would like to input the filename myself in the client (TX) side, where futher on I would include a JFileChooser for the user to select Graphically which file to send.
package file_rx;
import java.io.*;
import java.net.*;
public class File_RX implements Runnable
{
private static final int port = 4711;
private Socket socket;
public static void main(String[] _)
{
try
{
ServerSocket listener = new ServerSocket(port);
while (true)
{
File_RX file_rec = new File_RX();
file_rec.socket = listener.accept();
new Thread(file_rec).start();
}
}
catch (java.lang.Exception e)
{
e.printStackTrace(System.out);
}
}
public void run()
{
try
{
InputStream in = socket.getInputStream();
int nof_files = ByteStream.toInt(in);
for (int cur_file = 0; cur_file < nof_files; cur_file++)
{
String file_name = ByteStream.toString(in);
File file = new File(file_name);
ByteStream.toFile(in, file);
}
}
catch (java.lang.Exception e)
{
e.printStackTrace(System.out);
}
}
}
package file_tx;
import java.io.*;
import java.net.*;
public class File_TX
{
private static final int port = 4711;
private static final String host = "localhost";
public static void main(String[] args)
{
try
{
Socket socket = new Socket(host, port);
OutputStream os = socket.getOutputStream();
int cnt_files = args.length;
ByteStream.toStream(os, cnt_files);
for (int cur_file = 0; cur_file < cnt_files; cur_file++)
{
ByteStream.toStream(os, args[cur_file]);
ByteStream.toStream(os, new File(args[cur_file]));
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
package file_rx;
import java.io.*;
public class ByteStream
{
private static byte[] toByteArray(int in_int)
{
byte a[] = new byte[4];
for (int i = 0; i < 4; i++)
{
int b_int = (in_int >> (i*8)) & 255;
byte b = (byte) (b_int);
a[i] = b;
}
return a;
}
private static int toInt(byte[] byte_array_4)
{
int ret = 0;
for (int i = 0; i < 4; i++)
{
int b = (int) byte_array_4[i];
if (i < 3 && b < 0)
{
b = 256 + b;
}
ret += b << (i * 8);
}
return ret;
}
public static int toInt(InputStream in) throws java.io.IOException
{
byte[] byte_array_4 = new byte[4];
byte_array_4[0] = (byte)in.read();
byte_array_4[1] = (byte)in.read();
byte_array_4[2] = (byte)in.read();
byte_array_4[3] = (byte)in.read();
return toInt(byte_array_4);
}
public static String toString(InputStream ins) throws java.io.IOException
{
int len = toInt(ins);
return toString(ins, len);
}
private static String toString(InputStream ins, int len) throws java.io.IOException
{
String ret = new String();
for (int i = 0; i < len; i++)
{
ret += (char) ins.read();
}
return ret;
}
public static void toStream(OutputStream os, int i) throws java.io.IOException
{
byte [] byte_array_4 = toByteArray(i);
os.write(byte_array_4);
}
public static void toStream(OutputStream os, String s) throws java.io.IOException
{
int len_s = s.length();
toStream(os, len_s);
for (int i = 0; i < len_s; i++)
{
os.write((byte) s.charAt(i));
}
os.flush();
}
private static byte[] toByteArray(InputStream ins, int an_int) throws java.io.IOException
{
byte[] ret = new byte[an_int];
int offset = 0;
int numRead = 0;
int outstanding = an_int;
while ((offset < an_int) && (numRead = ins.read(ret, offset, outstanding)) > 0)
{
offset += numRead;
outstanding = an_int - offset;
}
if (offset < ret.length)
{
//throw new Exception("Could not completely read from stream, numRead =" + numRead + ", ret.lenght = " + ret.length);
}
return ret;
}
private static void toFile(InputStream ins, FileOutputStream fos, int len, int buf_size) throws java.io.IOException, java.io.FileNotFoundException
{
byte[] buffer = new byte[buf_size];
int len_read = 0;
int total_len_read = 0;
while (total_len_read + buf_size <= len)
{
len_read = ins.read(buffer);
total_len_read += len_read;
fos.write(buffer, 0, len_read);
}
if (total_len_read < len)
{
toFile(ins, fos, len - total_len_read, buf_size / 2);
}
}
private static void toFile(InputStream ins, File file, int len) throws java.io.IOException, java.io.FileNotFoundException
{
FileOutputStream fos = new FileOutputStream(file);
toFile(ins, fos, len, 1024);
}
public static void toFile (InputStream ins, File file) throws java.io.IOException, java.io.FileNotFoundException
{
int len = toInt(ins);
toFile(ins, file, len);
}
public static void toStream(OutputStream os, File file) throws java.io.IOException, java.io.FileNotFoundException
{
toStream(os, (int) file.length());
byte b[] = new byte[1024];
InputStream is = new FileInputStream(file);
int numRead = 0;
while ((numRead = is.read(b)) > 0)
{
os.write(b, 0, numRead);
}
os.flush();
}
}
The names (and paths) of the files to be transmitted are specified as arguments to the main method in the File_TX class. On the server side (File_RX class), the files will be saved relatively to the current directory of the File_RX.class file, having the same relative path as the input arguments above.

Constructing image from Grayvalues

I have extracted the Gray Value from an image file (format .3pi) and wrote them in file (Code below)-
public class ImageFile {
public static void main(String[] args) throws IOException {
FileInputStream fstream = new FileInputStream ("Z:\\20100204-000083-011.3pi");
DataInputStream in = new DataInputStream (fstream);
BufferedReader reader = new BufferedReader (new InputStreamReader (in));
String str = "";
String temp [];
int counter = 0, NumberOfColumn = 0, NumberOfRow = 0;
try {
while (counter != 3) {
str = reader.readLine();
counter ++;
if (counter == 2) {
temp = str.split(" ");
NumberOfRow = Integer.valueOf(temp[5].trim()).intValue();
}
else if (counter == 3) {
temp = str.split(" ");
NumberOfColumn = Integer.valueOf(temp[3].trim()).intValue();
}
}
}
catch (FileNotFoundException e){
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
//System.out.println ("Row : "+NumberOfRow);
//System.out.println ("Column : "+NumberOfColumn);
int found = 0, CurrentColumn = 0, CurrentRow = 0, GrayValue;
int image [][] = new int [NumberOfRow][NumberOfColumn];
FileInputStream fstream2 = new FileInputStream ("Z:\\20100204-000083-011.3pi");
DataInputStream in2 = new DataInputStream (fstream2);
BufferedReader reader2 = new BufferedReader (new InputStreamReader (in2));
FileWriter fstream3 = new FileWriter("Z:\\Test.txt",true);
BufferedWriter writer = new BufferedWriter (fstream3);
while ((str = reader2.readLine()) != null) {
str = str.trim();
temp = str.split(" ");
if (temp [0].contentEquals("#:Profile:")) {
CurrentColumn = Integer.valueOf(temp[1].trim()).intValue();
//System.out.println ("Current Column : "+CurrentColumn);
found = 1;
continue;
}
else {
if (found == 1) {
CurrentRow = Integer.valueOf(temp[4].trim()).intValue();
GrayValue = Integer.valueOf(temp[3].trim()).intValue();
image [CurrentRow][CurrentColumn] = GrayValue;
}
}
}
for (int i= 0; i< NumberOfRow; i++){
for (int j= 0; j< NumberOfColumn; j++){
writer.write (image [i] [j]+" ");
}
writer.write("\n");
}
writer.close();
}
}
Now, I want to create a jpg/ bmp/ any other image with the Gray value information in Test.txt file. How can I achieve it? Help appreciated.
Zereen
The Java Image I/O API Guide should provide with a lot of useful information about image I/O in Java.
If you have pixel data (the colors you would like to use), you can use the class Graphics2D (part of AWT) to draw on a BufferedImage (part of AWT) as described here. You can then use ImageIO to write the data. So:
try {
BufferedImage off_Image =
new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = off_Image.createGraphics();
for (int i= 0; i< NumberOfRow; i++) {
for (int j= 0; j< NumberOfColumn; j++) {
g2.setColor(new Color(....)); // here convert the value in image[i][j] to aRGB
g2.draw(new Rectangle(i, j, 1, 1);
}
}
File outputfile = new File("saved.png");
ImageIO.write(bi, "png", outputfile);
} catch (IOException e) {
// handle exception
}

Categories