Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

creating image from double[][]

4,807 views
Skip to first unread message

harryos

unread,
Jul 17, 2008, 1:59:05 AM7/17/08
to
hi
i have a double[][] that contains data of an image.I would like to
know how i can create a BufferedImage from this.I also want to convert
the data to greyscale values .I couldn't figure out how to use
javax.imageio methods to do this

thanks
harry

Peter Duniho

unread,
Jul 17, 2008, 2:07:06 AM7/17/08
to

Hard to answer with such a vague question. But probably the javax.imageio
package isn't of use here. Instead, you probably want the stuff in
java.awt.image, including BufferedImage and WriteableRaster.

Without more specifics about the format of your original "double" data,
it's impossible to suggest how a conversion to greyscale might work. But
assuming nothing unusual, it's probably just a matter of an arithmetic
scaling from the range of the original data to an 8-bit value from 0 to
255.

Pete

harryos

unread,
Jul 17, 2008, 7:52:12 AM7/17/08
to
On Jul 17, 11:07 am, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:

> Without more specifics about the format of your original "double" data, it's impossible to suggest how a conversion to greyscale might work.

hi Pete,

i am reading an image
BufferedImage img=ImageIO.read(new File("someimage.png"));
int wd=img.getWidth();
int ht=img.getHeight();
int[] rgbArray=new int[wd*ht];
img.getRGB(0, 0,wd,ht,rgbArray,0,wd);

then i am converting the int[] rgbArray into a double[] sothat my
application can process the pixel values.For this i do something like

for each pixel at index i,
int pixel=rgbArray[i];
int alpha=(pix >> 24) & 0x0ff;(i found these in one of your prev
posts ,thanks!)
int r=(pix>>16)& 0x0ff;
int g=(pix>>8)& 0x0ff;
int b=pix & 0x0ff;

then i take average of r,g,b so that i may get a greyscale value
double grey=(r+g+b)/3.0

using these i create a double[][] since i know the width & height of
image
Now i would like to create an image from this double[][] (or after
some processing is done on these double values).That is where i would
like some help
I couldn't figure out how to create the image from such an array
thanks
harry

Jack Marsh

unread,
Jul 17, 2008, 8:55:25 AM7/17/08
to
harryos wrote:
>
> then i take average of r,g,b so that i may get a greyscale value
> double grey=(r+g+b)/3.0

That would be a big mistake. Rather than treating red, green and blue as
equals, they must be weighted... one common scheme is

RGB Luminance value = 0.3 R + 0.59 G + 0.11 B


Consider for example what (r+g+b)/3.0 would do if the image were
composed entirely of red, green and blue bars. The result would be gray
= 1/3 everywhere. Leaving you with a totally uniform gray image with no
details. The Luminance formula takes into account the reaction of the
eye to different parts of the visible spectrum. Human eyes are more
sensitive to green than to red or green for example. Note that the
coefficients in the Luminance formula add to 1.0, so White is properly
replicated.

Message has been deleted

Lord Zoltar

unread,
Jul 17, 2008, 9:39:56 AM7/17/08
to

I'm curious as to how the weights are determined. Was it through
experimentation and trial and error, or was there some theory behind
why THOSE numbers are better than others?

Neil Coffey

unread,
Jul 17, 2008, 10:45:22 AM7/17/08
to
Lord Zoltar wrote:

>> RGB Luminance value = 0.3 R + 0.59 G + 0.11 B

[...]


> I'm curious as to how the weights are determined. Was it through
> experimentation and trial and error, or was there some theory behind
> why THOSE numbers are better than others?

It's probably from experiments conducted by the CIE
(Commission Internationale de l'Éclairage) -- many colour-related
techniques used in computing are.

Neil

Neil Coffey

unread,
Jul 17, 2008, 10:53:09 AM7/17/08
to
harryos wrote:

> then i am converting the int[] rgbArray into a double[] sothat my
> application can process the pixel values.For this i do something like

[...]


> then i take average of r,g,b so that i may get a greyscale value
> double grey=(r+g+b)/3.0

So ignoring double arrays, the basic underlying thing you want to do
is convert an image to greyscale, right? In which case, why not:

- create a new greyscale BufferedImage
- get a graphics context to the greyscale image
(with createGraphics());
- render your original image to the greyscale image's graphics
context?
- use your shiny new greyscale image for whatever purpose.

You probably want to set the 'colour accuracy' rendering hint on
the graphics context. As someone has pointed out, just averaging
the RGB values isn't a great conversion (although it's commonly used).

Neil

jimgardener

unread,
Jul 17, 2008, 11:48:49 AM7/17/08
to
On Jul 17, 10:59 am, harryos <oswald.ha...@gmail.com> wrote:
> hi i have a double[][] that contains data of an image.I would >like to know how i can create a BufferedImage from this.I also >want to convert the data to greyscale values .


I am not the owner of this code ,but i found this by googling.Also i
have some doubt as to the casting to short from double.But this gives
a 'toned down' greyscale image when i run this with a truecolor or
greyscale input image.The image is not as dark as the original one.I
don't know how to remedy that.Can some experts comment on this code.

public static BufferedImage CreateImageFromMatrix(double[] img, int
width) {
int[] grayImage = new int[img.length];
double[] scales = (double[])img.clone();
Arrays.sort(scales);
double min = scales[0];
double max = scales[scales.length - 1];
for(int i = 0; i < grayImage.length; i++) {
double v = img[i];
v -= min;
v /= (max - min);
short val = (short)(v * 255);
grayImage[i] = (val << 16) | (val << 8) | (val);
}
BufferedImage bi = new BufferedImage(width, img.length / width,
BufferedImage.TYPE_INT_RGB);
bi.setRGB(0, 0, width, img.length / width, grayImage, 0, width);
return bi;
}

regards
Jim

Knute Johnson

unread,
Jul 17, 2008, 12:53:55 PM7/17/08
to

Or for that matter use a ColorConvertOp which is even faster.

--

Knute Johnson
email s/nospam/knute2008/

--
Posted via NewsDemon.com - Premium Uncensored Newsgroup Service
------->>>>>>http://www.NewsDemon.com<<<<<<------
Unlimited Access, Anonymous Accounts, Uncensored Broadband Access

John B. Matthews

unread,
Jul 17, 2008, 2:23:35 PM7/17/08
to
In article
<4a6e47d6-6535-4869...@y38g2000hsy.googlegroups.com>,
jimgardener <jimga...@gmail.com> wrote:

Assuming positive elements in img, each v is scaled to the range 0.0 ..
1.0. Multiplication by 255 scales to the range 0 .. 255. The narrowing
to short seems OK. I'd be more worried about division by zero. This
looks like a simple way to spread the given values evenly across the
limited grayscale real estate.

Is Arrays.sort() [O(n*log(n))] a reasonable alternative to a single
min/max pass [O(n)] through array?

--
John B. Matthews
trashgod at gmail dot com
home dot woh dot rr dot com slash jbmatthews

Knute Johnson

unread,
Jul 17, 2008, 2:40:25 PM7/17/08
to

If you want to convert a color image to grayscale, use the tools in the
API. It is much simpler and much faster.

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;

public class ConvertToGray extends JPanel {
BufferedImage gray;

public ConvertToGray() {
try {
// read an image from the disk
BufferedImage image = ImageIO.read(new File("kittens.jpg"));

setPreferredSize(new Dimension(
image.getWidth(),image.getHeight()));

// create a grayscale image the same size
gray = new BufferedImage(image.getWidth(),image.getHeight(),
BufferedImage.TYPE_BYTE_GRAY);

// convert the original colored image to grayscale
ColorConvertOp op = new ColorConvertOp(
image.getColorModel().getColorSpace(),
gray.getColorModel().getColorSpace(),null);
op.filter(image,gray);

} catch (IOException ioe) {
ioe.printStackTrace();
}
}

public void paintComponent(Graphics g) {
g.drawImage(gray,0,0,null);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

ConvertToGray ctg = new ConvertToGray();
f.add(ctg,BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
});

Lew

unread,
Jul 17, 2008, 10:49:37 PM7/17/08
to

Clap.


Clap.


Clap.

Clap.

Clap.
Clap.
Clap. Clap. Clap. Clap. Clap. Clap. Clap. Clap.

Bravo!

--
Lew

harryos

unread,
Jul 18, 2008, 2:47:39 AM7/18/08
to
> If you want to convert a color image to grayscale, use the tools in the API. It is much simpler and much faster.


thanks sir,that was a good pointer.
however i need to create an image from an incoming double[] .something
like what jim gave above
ie BufferedImage CreateImageFromMatrix(double[] img, int
width)

i tried it..but it gives a slightly faded image when i provide it a
double[] derrived from another greyscale image.I think some scaling is
to be done to make it brighter?

harry

John B. Matthews

unread,
Jul 18, 2008, 11:45:58 AM7/18/08
to
In article
<abf09797-8bb5-4ab9...@v26g2000prm.googlegroups.com>,
harryos <oswald...@gmail.com> wrote:
[...]
> [I] need to create an image from an incoming double[] .something like
> what jim gave above ie BufferedImage CreateImageFromMatrix(double[]
> img, int width)

Referring to that code, again:

> for(int i = 0; i < grayImage.length; i++) {
> double v = img[i];
> v -= min;
> v /= (max - min);
> short val = (short)(v * 255);
> grayImage[i] = (val << 16) | (val << 8) | (val);
> }

Noting, again: "Assuming positive elements in img, each v is scaled to

the range 0.0 .. 1.0. Multiplication by 255 scales to the range 0 ..
255."

> [I] tried it..but it gives a slightly faded image when [I]provide it

> a double[] derrived from another greyscale image.

Is this surprising? You have taken some number of values and spread them
across the entire 256-valued gamut from white to black. If the image
appears faded, what can you infer about the distribution of values in
your source image? You can examine its histogram using, for example,
ImageJ:

<http://rsb.info.nih.gov/ij/>

Compare this to the histogram from your converted image.

> I think some scaling is to be done to make it brighter?

Yes.

Knute Johnson

unread,
Jul 18, 2008, 11:48:32 AM7/18/08
to

Take a look at WritableRaster, it has methods to take double[] and set
the pixels. You can then get a BufferedImage and use the ColorConverOp
to change it to grayscale.

Lew

unread,
Jul 18, 2008, 11:50:44 AM7/18/08
to

Clap.


Clap.


Clap.

Clap.

Clap.
Clap.
Clap. Clap. Clap. Clap. Clap. Clap. Clap. Clap.

Bravo!

--
Lew


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[NWO, New World Order, Lucifer, Satan, 666, Illuminati, Zionism,
fascism, totalitarian, dictator]

"The Cold War should no longer be the kind of obsessive
concern that it is. Neither side is going to attack the other
deliberately...If we could internationalize by using the U.N.
in conjunction with the Soviet Union, because we now no
longer have to fear, in most cases, a Soviet veto, then we
could begin to transform the shape of the world and might
get the U.N. back to doing something useful...Sooner or
later we are going to have to face restructuring our
institutions so that they are not confined merely to the
nation-states. Start first on a regional and ultimately you
could move to a world basis."

--- George Ball,
Former Under-secretary of State and CFR member
January 24, 1988 interview in the New York Times

0 new messages