Raster file to an image
How would I go about turning a series of numbers separated by commas (such as [url="http://www.geog.leeds.ac.uk/courses/postgrad/geog5560/projects/best.geology"]here[/url]). Into an image of some sort?
I assume an array of some kind but I don't know how to set up such thing. Any advice on the thought process behind what I need. I'm still very inexperienced with computer programming so unsure where to start let alone the technical aspect of what I need to do!
Thanks
[490 byte] By [
geo3gjsa] at [2007-11-26 14:51:38]

you might try an image processing or java 2d tutorial
the image constructors will take a byte array
so if you have the raster/pixel values in an array, you can easily create the image object
i'd recommend starting with ImageIcon
http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/ImageIcon.html
Sorry this is should be in the New to Java part of the forum. Oh dear.
What code would it require to get say a file named "population.txt" (a file composed of afforementioned comma-separated numbers between 0-255) into a byte array?I'm (comparitavely) ok at handling the array to create an image, but stumbling at this initial step.
1. Read the file one line at a time: http://www.exampledepot.com/egs/java.io/ReadLinesFromFile.html
2. Split each line, perhaps using [url=http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#split(java.lang.String)]String.split[/url]
3. Step two yields strings like "0" and "255". These need to be parsed, say by [url=http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Integer.html#parseInt(java.lang.String)]Integer.parseInt[/url].
Using Byte's parse methods may not work because I recall they assume the strings represent signed bytes (-128 to 127) not unsigned (0 to 255).
I've tried to follow the 3 steps above and came up with:
import java.io.*;
import java.util.*;
public class Str {
public static void main (String[] args){
try {
BufferedReader in = new BufferedReader(new FileReader("pop.txt"));
String str;
while ((str = in.readLine()) != null) {
String st = str;
String[] arr = st.split ("\\,");
for (int i=0; i < arr.length; i++)
Integer.parseInt (st);
}
in.close();
} catch (IOException e) {
System.out.println("IOException");
}
}
}
The overall thing I'm looking to achieve is:
1. To pass the .txt file in. (Format 0,0,2,3,5,6,6 etc. over many lines)
2. It to run through line by line and pick up the integers.
3. To store these in some sort of array (the .txt file is 335 by 530 ints)
4. Using the array assign a rgb value = to the int
5. To create an image from this.
Am I on the right tracks with the code above? This is certainly pushing my tiny knowledge of java so hopefully someone can give me a shunt in the right direction.
What if I set up a 2D array in another class seeing as I know the exact size it should be [335] [530]? Is it possible to copy/read the String.split and Integer.parseInt numbers into this 2D array whilst they are being split and parsed so to speak?
> What if I set up a 2D array in another class seeing
> as I know the exact size it should be [335] [530]? Is
> it possible to copy/read the String.split and
> Integer.parseInt numbers into this 2D array whilst
> they are being split and parsed so to speak?
To create an image from an array of int's or byte's, you need a 1d array, so I suggest not to create a 2d but a 1d array at once.
Here's a start:
import java.io.*;
import java.util.*;
public class Str {
public static void main (String[] args){
int[] pixels = readFile("pop.txt");
}
public static int[] readFile(String fileName) {
List<Integer> numbers = new ArrayList<Integer>();
try {
BufferedReader in = new BufferedReader(new FileReader(fileName));
String str;
while ((str = in.readLine()) != null) {
String st = str;
String[] arr = st.split ("\\,");
for (int i=0; i < arr.length; i++) {
// remove leading and/or trailing spaces
String num = arr[i].trim();
// put the number in the dynamic list
numbers.add(new Integer(num));
}
}
in.close();
} catch(Exception e) {
System.out.println(e);
}
// 1 - create an int-array with the same size as your dynamic list
// 2 - loop through you list and add each Integer in your array of
//int's using Integer.intValue() method
// 3 - return your array of int's
}
}
> System.out.println("Exception");> System.out.println(e);Guys, please print the stack traces. :)
> Guys, please print the stack traces. :)I was too lazy, and thought it would get unnoticed on a quiet Sunday...; )Won't happen again, sir!
// 1 - create an int-array with the same size as your dynamic list
// 2 - loop through you list and add each Integer in your array of
//int's using Integer.intValue() method
// 3 - return your array of int's
//I've created an int array, but don't know how to make its
//size equal to that of the dynamic list?
int[] popArray = new int[numbers];
for (int i=0; i < popArray.length; i++) {
//It will loop through the int array, but unsure how to use the
//Interger.intValue () method.
}
return popArray;
}
> //I've created an int array, but don't know how to make its
> //size equal to that of the dynamic list?
Have a look at the API docs for the List interface then:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html
look at a method which returns an int that could represent the size (hint) of the List.
Ok I understand that your telling me there is a size method with regards to the arraylist called 'numbers' in the code. I don't know how to call on it and use it to get the size.
Should it appear something like this although this unsurprisingly fails to compile? I need to find the size with respect to numbers so assume the words numbers and size must appear somewhere.
int s = numbers.size;
int[] popArray = new int[s];
The most frustrating thing is that even if I do manage this minor miracle and get a series of numbers into an array I then need to be able to make an image from it (which again is clearly beyond my ability if I can't do the simple part and get a .txt file into an array in the format I want!). On top of that I need to do this to 3 similar .txt files and merge said 3 images. On top of that the user needs to beable to weight each of the overlayed images using convieniently placed scrollbars. Oh dear I'm a lost cause.
Message was edited by:
geo3gjs
> Ok I understand that your telling me there is a size
> method with regards to the arraylist called 'numbers'
> in the code. I don't know how to call on it and use
> it to get the size.
>
> Should it appear something like this although this
> unsurprisingly fails to compile? I need to find the
> size with respect to numbers so assume the words
> numbers and size must appear somewhere.
>
> int s = numbers.size;
> int[] popArray = new int[s];
Now you're trying to acces an attribute (variable) from your dynamic list. You have to call the method which get the size of th list. (how do you call other methods?)
> The most frustrating thing is that even if I do
> manage this minor miracle and get a series of numbers
> into an array I then need to be able to make an image
> from it (which again is clearly beyond my ability if
> I can't do the simple part and get a .txt file into
> an array in the format I want!). On top of that I
> need to do this to 3 similar .txt files and merge
> said 3 images. On top of that the user needs to
> beable to weight each of the overlayed images using
> convieniently placed scrollbars. Oh dear I'm a lost
> cause.
Then start with something that lies in the scope of your abilities. Once you have practiced more, you will be able to do this.
>Then start with something that lies in the scope of your abilities. Once >you have practiced more, you will be able to do this.
Unfortunately I was silly enough to decide that 'Introduction to Java' for those with no computer programming experience was for me and picked it as a fabulous post-grad module. The joy. This final project is the proverbial 'lambs to the slaughter' where my introduction knowledge is proven just that and if I'm honest confidence rather in tatters with java!
Thank you for your patience and help.
> ...> Thank you for your patience and help.You're most welcome. Best of luck.
With regards to calling this method am I getting any warmer with numbers.getSize() or icier?
And perhaps more importantly (that I forgot to add). If this is all in say 'class Str', will I be able to call on this elusive array from another class to get it to make an image?
The alternative is to cut my losses and expend the effort on making an image from random numbers in an array. At least then I may have something to show for the blood, sweat and many tears.
> With regards to calling this method am I getting any
> warmer with numbers.getSize() or icier?
Nope. Guessing won't get you there.
; )
I know they're a bit overwhelming at the beginning, but they're a must: the Java API docs.
This is the API doc for the java.util.List interface (java.util.ArrayList implements the List interface, so every method defined in java.util.List has to be implemented by java.util.ArrayList, thus can be called from your "numbers" variable):
http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html
All API docs are built up in this fashion:
1 - package structure
2 - discription of the class/interface
3 - field summary (class variables)
4 - constructor summary
5 - method summary
6 - ...
Since our List is an interface and has no fields or constructors, you can head straight for the method summary. There you find (near the end) this entry:
+--++
| int | size() |
||Returns the number of elements in this list.|
+--++
The first column discribes what the return type of the method is (an int in this case). In the 2nd column the method itself and a smmall discription of it are displayed.
Clear?
> And perhaps more importantly (that I forgot to add).
> If this is all in say 'class Str', will I be able to
> call on this elusive array from another class to get
> it to make an image?
Always use descriptive class and method names.
I suggest using the following approach:/**
* The main class
*/
class Main {
public static void main(String[] args) {
try {
MyFile file = new MyFile("pop.txt");
int[] intArray = file.getNumbers();
MyImage image = new MyImage(intArray);
} catch(Exception e) {
e.printStackTrace();
}
}
}
/**
* A class which represents your file with numbers
*/
class MyFile {
private int[] numbers;
public MyFile(String fn) {
numbers = new int[0];
readNumbers(fn);
}
public int[] getNumbers() {
return numbers;
}
private void readNumbers(String fn) {
// read your numbers from file here
}
}
/**
* A class which represents your image
*/
class MyImage {
public MyImage(int[] numbers) {
// your code
}
// your code
}
> The alternative is to cut my losses and expend the
> effort on making an image from random numbers in an
> array. At least then I may have something to show for
> the blood, sweat and many tears.
No, I suggest getting the number-reading from file to work first: you're almost there.
Ahh then perhaps this is what I'm after:int s = numbers.size();That was silly of me.
> Ahh then perhaps this is what I'm after:> > int s = numbers.size();Bingo!> That was silly of me.Nah, we've all been there (I have at least).
I have used the size() method to find the size of the list. Created an array the same size as this so that is stage one done. As previously mentioned the next stage is to loop through the list and add each item into this array.
Here is the intValue method: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Integer.html#intValue()
And I can see with respect to each number in the loop I need to use this method. I can start the array looping with the following code, but I'm not sure how to get the list to match up to this so I can use the intValue() method?
for (int i=0; i < popArray.length; i++) {
}
> I have used the size() method to find the size of the
> list. Created an array the same size as this so that
> is stage one done. As previously mentioned the next
> stage is to loop through the list and add each item
> into this array.
>
> Here is the intValue method:
> http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Inte
> ger.html#intValue()
>
> And I can see with respect to each number in the loop
> I need to use this method. I can start the array
> looping with the following code, but I'm not sure how
> to get the list to match up to this so I can use the
> intValue() method?
Here's a hint:
for (int i=0; i < popArray.length; i++) {
// get the i-th element from your dynamic list (check the API docs)
Integer intObject = ?
popArray[i] = intObject. ?
}
I see a toArray() in the ArrayList docs is that useful or have I gone cold again?
http://java.sun.com/j2se/1.4.2/docs/api/java/util/ArrayList.html#toArray()
I think the second part of the hint is:
popArray[i] = intObject.intValue();
Message was edited by:
geo3gjs
> I see a toArray() in the ArrayList docs is that
> useful or have I gone cold again?
>
> http://java.sun.com/j2se/1.4.2/docs/api/java/util/ArrayList.html#toArray()
Unfortunately, that's a no-go.
An ArrayList (or any collection from the java.util package) can only hold Objects. That's why you can't store primitives as int's directly in them. You have to "wrap" those primitives (int, double, boolean, etc.) into their wrapper classes. So that ArrayList does not hold int's but Integer's.
So with toArray() you could only get an Integer[], not an int[].
The for-statement is the way to go.
> ...> I think the second part of the hint is:> >popArray = intObject.intValue();That is correct. Now you only have to get a specific object from the list.
ahh ok again silly me:Integer intObject = numbers.get(i);
Is there a specific way I can test that it'll work. For example pick out the value in 1st position and print it to the command box. It should be 335.
If I do a System.out.println in the for loop it compiles, but doesn't seem to want to outside of it.
for (int i=0; i < popArray.length; i++) {
// get the i-th element from your dynamic list (check the API docs)
Integer intObject = numbers.get(i);
popArray[i] = intObject.intValue();
System.out.println(i);
}
return popArray;
}
}
What doesSystem.out.println(popArray.length);print?
The number 177552 repeatedly probably 177552 times.Which is the total numbers in the .txt file 335*530 + the number 335 and 530 at the top to tell me the size = 177552.Message was edited by: geo3gjs
> If I do a System.out.println in the for loop it
> compiles, but doesn't seem to want to outside of it.
Ah, I misunderstood. The 'i' can only be seen inside the for loop.
When your int[] gets returned, you can loop through that array to see if the values are correct.
In order to test by printing the .txt file from start to finish where should I put this loop?
int s = numbers.size();
int[] popArray = new int[s];
for (int i=0; i < popArray.length; i++) {
Integer intObject = numbers.get(i);
popArray[i] = intObject.intValue();
}
return popArray;
//The array is returned here yet I can't
//imagine setting up a loop would work in this position?
}
}
Spotted my own error it should be above the for loop adding the values from the ArrayList.
> In order to test by printing the .txt file from start
> to finish where should I put this loop?
import java.io.*;
import java.util.*;
public class Str {
public static void main (String[] args){
int[] pixels = readFile("pop.txt");
System.out.println(pixels[2]);// prints the 3rd element
}
public static int[] readFile(String fileName) {
// your code which returns an int-array
}
}
Indeed it does! Fantastic! Should I be concerned by the java.lang.NumberFormatException: For input String: " " error that is printed?The command box reads:java.lang.NumberFormatException: For input String: " "335335 being the correct answer for the
> Indeed it does! Fantastic!
>
> Should I be concerned by the
> java.lang.NumberFormatException: For input String: "
> " error that is printed?
>
> The command box reads:
>
> java.lang.NumberFormatException: For input String: "
> "
> 335
>
> 335 being the correct answer for the pixel[0].
Yes, you should be concerned. You are probably parsing a number with 1 or more whitespaces, tabs or line-breaks.
The following will not compile (try it):
String line = "1, 2, 3";
String[] stringArray = line.split("\\,");
int[] intArray = new int[stringArray.length];
for(int i = 0; i < intArray.length; i++) {
intArray[i] = Integer.parseInt(stringArray[i]);
}
Now replace the line within the for-statement with this:intArray[i] = Integer.parseInt(stringArray[i].trim());
Message was edited by:
prometheuzz
One slight hitch that I can forsee is that the numbers are set out to form a rough out line of the UK:
http://www.geog.leeds.ac.uk/courses/postgrad/geog5560/projects/best.pop
I imagined this was important in creating the shape of the image:
http://www.geog.leeds.ac.uk/courses/postgrad/geog5560/projects/bestpop.gif
> One slight hitch that I can forsee is that the
> numbers are set out to form a rough out line of the
> UK:
>
> http://www.geog.leeds.ac.uk/courses/postgrad/geog5560/projects/best.pop
>
> I imagined this was important in creating the shape
> of the image:
> http://www.geog.leeds.ac.uk/courses/postgrad/geog5560/projects/bestpop.gif
I see that only the first line needs to be splitted with a comma as a delimeter, the rest is needs tp be splitted using a whitespace.
The first line 335,530 will be removed.The rest I assumed needed comma delimiters as I see commas between each number. I don't know how to deal with the white space as I'm guessing its essential to creating the right image.
Although if it is automatically assigned the integer 0 then it'll be fine?
> The first line 335,530 will be removed.
>
> The rest I assumed needed comma delimiters as I see
> commas between each number. I don't know how to deal
> with the white space as I'm guessing its essential to
> creating the right image.
Sorry, I was hallucinating. You are right; there are no whitespaces but comma's.
; )
Not sure what the exact problemn now is.
It's late here: I'm going to hit the sack.
Does anyone know why a java.lang.NumberFormatException: For Input String: "" occurs with the following code and more importantly how to fix it?
The .txt file is a select all, copy & paste job from here:
http://www.geog.leeds.ac.uk/courses/postgrad/geog5560/projects/best.pop
import java.io.*;
import java.util.*;
public class Str {
public static void main (String[] args){
int[] pixels = readFile("pop.txt");
System.out.println(pixels[0]);
}
public static int[] readFile(String fileName) {
List<Integer> numbers = new ArrayList<Integer>();
try {
BufferedReader in = new BufferedReader(new FileReader(fileName));
String str;
while ((str = in.readLine()) != null) {
String st = str;
String[] arr = st.split ("\\,");
for (int i=0; i < arr.length; i++) {
// remove leading and/or trailing spaces
String num = arr[i].trim();
// put the number in the dynamic list
numbers.add(new Integer(num));
}
}
in.close();
} catch(Exception e) {
System.out.println(e);
}
int s = numbers.size();
int[] popArray = new int[s];
for (int i=0; i < popArray.length; i++) {
Integer intObject = numbers.get(i);
popArray[i] = intObject.intValue();
}
return popArray;
}
}
What number does "" represent?Exactly. That's why you're getting a NumberFormatException.Well, you can skip empty strings, you can catch and ignoreNumberFormatExceptions ...
Ok how can I skip empty strings? Any clues?
I don't get a NumberFormatException when I run your code on the.txt file you provided.The image doesn't look like much to me, though. Kinda like ablue duck.
Oh no that sounds like more trouble. Here is what it is supposed to look like if the int at each position is set equal to the rgb values: http://www.geog.leeds.ac.uk/courses/postgrad/geog5560/projects/bestpop.gif
That doesn't look like a sideways duck to you? :)That's what I got.
I see where you got the duck now! I've been puzzling over the image until I spotted a beak and then the wings if you turn it 90 degrees clockwise.