thanks
harry
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
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
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.
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?
>> 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
> 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
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
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
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
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);
}
});
Clap.
Clap.
Clap.
Clap.
Clap.
Clap.
Clap. Clap. Clap. Clap. Clap. Clap. Clap. Clap.
Bravo!
--
Lew
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
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:
Compare this to the histogram from your converted image.
> I think some scaling is to be done to make it brighter?
Yes.
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.
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