I need to display a PNG image in a SWT Java window, I'm using WindowBuilder and Eclipse.
First I tried with a label and this code:
Label lblNewLabel = new Label(this, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 1));
Image image = new Image(display, "img/selae_mini.png");
lblNewLabel.setImage(image)
It worked when executing in eclipse, but when I generate the jar, then, it doesn't work. Then I found on Stack Overflow that you must use ClassLoader.getSystemClassLoader().getResourceAsStream to get a bufferedImage and after that you must convert that bufferedImage to a ImageData, and finally convert that into a SWT Image.
So I tried with this code:
protected Image readImage(String path, Display display) {
InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream(path);
BufferedImage bi = null;
try {
bi = ImageIO.read(stream);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (stream != null)
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return new Image(display, convertToSWT(bi));
}
public static ImageData convertToSWT(BufferedImage bufferedImage) {
if (bufferedImage.getColorModel() instanceof DirectColorModel) {
DirectColorModel colorModel = (DirectColorModel) bufferedImage.getColorModel();
PaletteData palette = new PaletteData(
colorModel.getRedMask(),
colorModel.getGreenMask(),
colorModel.getBlueMask()
);
ImageData data = new ImageData(
bufferedImage.getWidth(),
bufferedImage.getHeight(), colorModel.getPixelSize(),
palette
);
WritableRaster raster = bufferedImage.getRaster();
int[] pixelArray = new int[3];
for (int y = 0; y < data.height; y++) {
for (int x = 0; x < data.width; x++) {
raster.getPixel(x, y, pixelArray);
int pixel = palette.getPixel(
new RGB(pixelArray[0], pixelArray[1], pixelArray[2])
);
data.setPixel(x, y, pixel);
}
}
return data;
} else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
IndexColorModel colorModel = (IndexColorModel) bufferedImage.getColorModel();
int size = colorModel.getMapSize();
byte[] reds = new byte[size];
byte[] greens = new byte[size];
byte[] blues = new byte[size];
colorModel.getReds(reds);
colorModel.getGreens(greens);
colorModel.getBlues(blues);
RGB[] rgbs = new RGB[size];
for (int i = 0; i < rgbs.length; i++) {
rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
}
PaletteData palette = new PaletteData(rgbs);
ImageData data = new ImageData(
bufferedImage.getWidth(),
bufferedImage.getHeight(),
colorModel.getPixelSize(),
palette
);
data.transparentPixel = colorModel.getTransparentPixel();
WritableRaster raster = bufferedImage.getRaster();
int[] pixelArray = new int[1];
for (int y = 0; y < data.height; y++) {
for (int x = 0; x < data.width; x++) {
raster.getPixel(x, y, pixelArray);
data.setPixel(x, y, pixelArray[0]);
}
}
return data;
}
return null;
}
The problem now is that my Image is a PNG file, and when doing the IF of the convertToSWT method, it gets that the image has a ColorModel called #pixelBits, so it returns null on that method! and I can't find any info about how to solve this problem.
I had this problem in before, and i resolved that. assuming your image has located in resource folder of your project:
String yourImg = "sampleImg.png";
...
Label swtImg = new Label(composite, SWT.NONE);
swtImg.setImage(new Image(display, YourClassName.calss.getResourceAsStream(yourImg)));
it's worked for me!
good luck ;)
Related
The code below generates a GIF image that’s half red and half blue.
How can I get one that’s half red and half transparent?
I’ve tried using the IndexColorModel constructor that takes a transparent pixel index as a parameter, and also changing the image type to IMAGE_TYPE_ARGB in the call to the BufferedImage constructor, but nothing is working for me.
int pixels[] = new int[90000];
for (int x = 0; x < 300; x++) {
for (int y = 0; y < 300; y++) {
pixels[(300 * y) + x] = (x < y) ? 1 : 0;
}
}
Color oneColor = Color.red;
Color anotherColor = Color.blue;
byte[] redMap = {(byte) (oneColor.getRed()), (byte) (anotherColor.getRed())};
byte[] greenMap = {(byte) (oneColor.getGreen()), (byte) (anotherColor.getGreen())};
byte[] blueMap = {(byte) (oneColor.getBlue()), (byte) (anotherColor.getBlue())};
IndexColorModel colorModel = new IndexColorModel(1, 2, redMap, greenMap, blueMap);
MemoryImageSource mis = new MemoryImageSource(300, 300, colorModel, pixels, 0, 300);
Image image = Toolkit.getDefaultToolkit().createImage(mis);
BufferedImage bufferedImage = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
bufferedImage.getGraphics().drawImage(image, 0, 0, null);
try {
ImageIO.write(bufferedImage, "gif", new File("example.gif"));
} catch (IOException e) {
e.printStackTrace();
}
Turns out that BufferedImage.TYPE_BYTE_INDEXED is more appropriate for this case. This code does the trick:
Color oneColor = Color.blue;
Color anotherColor = Color.red;
byte[] redMap = {(byte) (oneColor.getRed()), (byte) (anotherColor.getRed())};
byte[] greenMap = {(byte) (oneColor.getGreen()), (byte) (anotherColor.getGreen())};
byte[] blueMap = {(byte) (oneColor.getBlue()), (byte) (anotherColor.getBlue())};
IndexColorModel colorModel = new IndexColorModel(1, 2, redMap, greenMap, blueMap, 0);
int transparency = colorModel.getTransparency();
int transparentPixel = colorModel.getTransparentPixel();
System.out.println("colorModel.getTransparency(): " + transparency);
System.out.println("colorModel.getTransparentPixel(): " + transparentPixel);
BufferedImage bufferedImage = new BufferedImage(300, 300, BufferedImage.TYPE_BYTE_INDEXED, colorModel);
WritableRaster writableRaster = bufferedImage.getRaster();
for (int x = 0; x < 300; x++) {
for (int y = 0; y < 300; y++) {
int[] fill = new int[1]; // A large block...
Arrays.fill(fill, (x < y) ? 0 : 1); // .. filled with one of the 7 first colors in the LUT.
writableRaster.setSamples(x, y, 1, 1, 0, fill);
}
}
In my experience, I changed the transparency of colors with alpha. For instance, transparent red looks like this:
Color transparentred = new Color (255, 0, 0, alpha);
Maybe try to set alpha for your redMap, blueMap, greenMap
I am getting the int array from png image how I will convert this to bufferdimage or creating new PNG file ?
int[] pixel = new int[w1*h1];
int i = 0;
for (int xx = 0; xx < h1; xx++) {
for (int yy = 0; yy < w1; yy++) {
pixel[i] = img.getRGB(yy, xx);
i++;
}
}
If you have an array of integers which are packed RGB values, this is the java code to save it to a file:
int width = 100;
int height = 100;
int[] rgbs = buildRaster(width, height);
DataBuffer rgbData = new DataBufferInt(rgbs, rgbs.length);
WritableRaster raster = Raster.createPackedRaster(rgbData, width, height, width,
new int[]{0xff0000, 0xff00, 0xff},
null);
ColorModel colorModel = new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
BufferedImage img = new BufferedImage(colorModel, raster, false, null);
String fname = "/tmp/whatI.png";
ImageIO.write(img, "png", new File(fname));
System.out.println("wrote to "+fname);
The reason for the arrays 0xff0000, 0xff00, 0xff is that the RGB bytes are packed with blue in the least significant byte. If you pack your ints different, alter that array.
You can rebuild the image manually, this is however a pretty expensive operation.
BufferedImage image = new BufferedImage(64, 64, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
for(int i = 0; i < pixels.size(); i++)
{
g.setColor(new java.awt.Color(pixels.get(i).getRed(), pixels.get(i).getGreen(), pixels.get(i).getBlue()));
g.fillRect(pixels.get(i).getxPos(), pixels.get(i).getyPos(), 1, 1);
}
try
{
ImageIO.write(image, "PNG", new File("imageName.png"))
}
catch(IOException error)
{
error.printStackTrace();
}
I formatted your image array into an object, this is personal preference tho (of course you could us an int array with this model as well). Keep in mind that you can always add the alpha to there as well.
Try the ImageIO class, which can take a byte array representing pixel data to build an image object and then writing it out in a particular format.
try {
BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(yourBytes));
ImageIO.write(bufferedImage, "png", new File("out.png"));
} catch (IOException e) {
e.printStackTrace();
}
I was just wondering what the best way to read pixels from a BufferedImage. I want the pixels contained in a int[].
Here is my code right now:
try {
BufferedImage img = ImageIO.read(new File("C:\\Users\\Hardish\\Pictures\\test.png"));
BufferedImage intimg = Util.convertBufferedImage(img, BufferedImage.TYPE_INT_RGB);
int[] pixels = ((DataBufferInt)intimg.getRaster().getDataBuffer()).getData();
int co = Util.randomColor(255).getRGB();
if(co < 0)
co = -co;
StringBuilder sb = new StringBuilder();
for(int i = 0; i < pixels.length; i++){
Pixel px = new Pixel(Util.convertPixel(i, img.getWidth()), pixels[i]);
sb.append(px.toCompactString(true));
pixels[i] += co;
}
ImageIO.write(intimg, "jpg", new FileOutputStream("C:\\Users\\Hardish\\Pictures\\test.jpg"));
SaveHandler.saveCompressed(sb.toString(), "C:\\Users\\Hardish\\Pictures\\test.dat");
SaveHandler.saveString(sb.toString(), "C:\\Users\\Hardish\\Pictures\\test.sdat");
String pixDat = (String)(SaveHandler.readCompressed("C:\\Users\\Hardish\\Pictures\\test.dat"));
String[] pixs = pixDat.split(Pixel.PIXEL_SEPARATOR);
int[] pixelsRead = new int[pixs.length];
for(int i = 0; i < pixelsRead.length; i++){
pixelsRead[i] = Pixel.parseCompactPixel(pixs[i], true).val;
}
BufferedImage img2 = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
int[] pixelsW = ((DataBufferInt)img2.getRaster().getDataBuffer()).getData();
for(int i = 0; i < pixelsW.length; i++){
pixelsW[i] = pixelsRead[i];
}
ImageIO.write(img2, "jpg", new FileOutputStream("C:\\Users\\Hardish\\Pictures\\testRead.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
Here is the original:
Here is the change the pixels output:
Here is the read from file output:
I am reading a .jpg image and accesing the pixels as:
if (type == BufferedImage.TYPE_3BYTE_BGR) {
System.out.println("type.3byte.bgr");
byte[] pixels = (byte[]) sourceImage.getData().getDataElements(0, 0, w, h, null);
}
// process this array called pixels and display the resulting image
// first i convert it to integer
int offseet=0;
int[] data=new int[width*height*3];
for ( i = 0; i < data.length; i++) {
data[i] = pixels[offset++] & 0xff;
}
// and then process this array. For now I am not processing it. Now when i create a buffered
//image from data array and display it the image displayed is not the same.
// the code i use is
writeEdges(data);
private BufferedImage edgesImage;
private void writeEdges(int arb[]) {
if (edgesImage == null) {
edgesImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
}
edgesImage.getWritableTile(0, 0).setDataElements(0, 0, width,height, arb);
}
// for the penguins.jpg image(provided in sample pictures in windows 7)!
the output i get is
I do not know how is your code running because it would not compile as jcomeau_ictx pointed out. The problem is that you use different image type for reading and writing.
Here is a code snippet that would generate the same image as the input.
public static void main(String[] args) {
BufferedImage sourceImage = null;
try {
sourceImage = ImageIO.read(new File("IScSH.jpg"));
} catch (IOException e) {
}
int type = sourceImage.getType();
int w = sourceImage.getWidth();
int h = sourceImage.getHeight();
byte[] pixels = null;
if (type == BufferedImage.TYPE_3BYTE_BGR) {
System.out.println("type.3byte.bgr");
pixels = (byte[]) sourceImage.getData().getDataElements(0, 0, w, h, null);
}
try {
BufferedImage edgesImage = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
edgesImage.getWritableTile(0, 0).setDataElements(0, 0, w, h, pixels);
ImageIO.write(edgesImage, "jpg", new File("nvRhP.jpg"));
} catch (IOException e) {
}
}
This question already has answers here:
Embed .swf file to my Jframe
(2 answers)
Closed 3 years ago.
JFrames or Java in general do they have some sort of flash plugin extension?
Thanks
As for Swing, I do not think so. But it should be possible with AWT - please find this link, that should give you an idea.
Here's an example which plays Flash via the Internet Explorer OCX plug-in, and can even capture screenshots from the Flash object. It needs SWT however.
Edit: Actually, not really. It looks like it does the SWT image conversion later. You can use the BufferedImage with a JComponent or something, just by drawing it.
/**
*
*/
package swfexp1;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.WritableRaster;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.ole.win32.OLE;
import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.OleClientSite;
import org.eclipse.swt.ole.win32.OleFrame;
import org.eclipse.swt.ole.win32.Variant;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import swfexp1.res.ResRoot;
public final class SWFExp1 {
private GC canvas, snapGC;
private Canvas snapCanvas;
private Shell shell;
private OleFrame frame;
//private OleControlSite oleCSite;
private OleClientSite oleClSite;
private OleAutomation oleAuto;
private Display display;
private long lastSnapshotMS = System.currentTimeMillis();
private long lastUpdateTimeMS = System.currentTimeMillis();
private Composite viewComp;
/**
*
*/
public SWFExp1() {
display = Display.getDefault();
shell = new Shell(display);
shell.setSize(1050, 550);
GridLayout l = new GridLayout(2, false);
shell.setLayout(l);
canvas = new GC(shell);
frame = new OleFrame(shell, SWT.NONE);
GridData d = new GridData();
frame.setLayoutData(d);
d = new GridData();
viewComp = new Composite(shell, SWT.BORDER);
viewComp.setLayoutData(d);
//viewComp.setBounds(0, 0, 500, 500);
snapCanvas = new Canvas(viewComp, SWT.NONE);
d = new GridData(500, 500);
snapCanvas.setLayoutData(d);
snapCanvas.setBounds(0, 0, 500, 500);
snapGC = new GC(snapCanvas);
//oleCSite = new OleControlSite(frame, SWT.NONE, "ShockwaveFlash.ShockwaveFlash");
oleClSite = new OleClientSite(frame, SWT.NONE, "ShockwaveFlash.ShockwaveFlash");
System.out.println("oleclsite: " + oleClSite);
oleClSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
oleClSite.doVerb(OLE.OLEIVERB_SHOW);
oleClSite.setBounds(0, 0, 500, 500);
oleAuto = new OleAutomation(oleClSite);
shell.setVisible(true);
shell.open();
int[] rgdispid = oleAuto.getIDsOfNames(new String[]{"Play"});
int playID = rgdispid[0];
System.out.println("playID: " + playID);
rgdispid = oleAuto.getIDsOfNames(new String[]{"Movie"});
int moviePropSetID = rgdispid[0];
System.out.println("moviePropSetID: " + moviePropSetID);
rgdispid = oleAuto.getIDsOfNames(new String[]{"Stop"});
int stopID = rgdispid[0];
System.out.println("stopID: " + stopID);
rgdispid = oleAuto.getIDsOfNames(new String[]{"Back"});
int backID = rgdispid[0];
System.out.println("backID: " + backID);
rgdispid = oleAuto.getIDsOfNames(new String[]{"Forward"});
int forwardID = rgdispid[0];
System.out.println("forwardID: " + forwardID);
rgdispid = oleAuto.getIDsOfNames(new String[]{"StopPlay"});
int stopPlayID = rgdispid[0];
System.out.println("stopPlayID: " + stopPlayID);
rgdispid = oleAuto.getIDsOfNames(new String[]{"LoadMovie", "layer", "url"});
int loadMovieID = rgdispid[0];
System.out.println("loadMovieID: " + loadMovieID);
Variant[] rgvarg = new Variant[2];
//String fileName = "file:///C:/Users/Public/blah/cubes.swf";
ResRoot r = new ResRoot();
String fileName = r.getClass().getResource("runanim.swf").toString();
fileName = fileName.replace("file:/", "file://");
System.out.println("fname: " + fileName);
rgvarg[0] = new Variant(0); // layer
rgvarg[1] = new Variant(fileName); // path
//Variant[] rgvarg2 = new Variant[1];
//String fileName2 = "C:\\Users\\Public\\blah\\cubes.swf";
//rgvarg2[0] = new Variant(fileName2);
//boolean done = oleAuto.setProperty(moviePropSetID, rgvarg[0]);
//System.out.println("done: " + done);
Variant pVarResult1 = oleAuto.invoke(loadMovieID, rgvarg);
Variant pVarResult2 = oleAuto.invoke(playID);
System.out.println("pvarr1: " + pVarResult1);
//System.out.println("pvarr2: " + pVarResult2);
}
public void run() {
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
lastUpdateTimeMS = System.currentTimeMillis();
if (lastUpdateTimeMS >= (lastSnapshotMS + 300)) {
takeSnap();
lastSnapshotMS = lastUpdateTimeMS;
}
}
oleAuto.dispose();
display.dispose();
}
/**
* Take snapshot and put it in the view
*/
private void takeSnap() {
System.out.println("cheese!");
Image i = new Image(canvas.getDevice(), 500, 500);
canvas.copyArea(i, 0, 0);
snapGC.drawImage(i, 0, 0);
//canvas.copyArea(snapCanvas.get, );
}
/**
* #param args
*/
public static void main(String[] args) {
SWFExp1 exp1 = new SWFExp1();
exp1.run();
}
public static final BufferedImage convertToAWT(ImageData data) {
ColorModel colorModel = null;
PaletteData palette = data.palette;
if (palette.isDirect) {
colorModel = new DirectColorModel(data.depth, palette.redMask, palette.greenMask, palette.blueMask);
BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null);
WritableRaster raster = bufferedImage.getRaster();
int[] pixelArray = new int[3];
for (int y = 0; y < data.height; y++) {
for (int x = 0; x < data.width; x++) {
int pixel = data.getPixel(x, y);
RGB rgb = palette.getRGB(pixel);
pixelArray[0] = rgb.red;
pixelArray[1] = rgb.green;
pixelArray[2] = rgb.blue;
raster.setPixels(x, y, 1, 1, pixelArray);
}
}
return bufferedImage;
}
// otherwise...
RGB[] rgbs = palette.getRGBs();
byte[] red = new byte[rgbs.length];
byte[] green = new byte[rgbs.length];
byte[] blue = new byte[rgbs.length];
for (int i = 0; i < rgbs.length; i++) {
RGB rgb = rgbs[i];
red[i] = (byte) rgb.red;
green[i] = (byte) rgb.green;
blue[i] = (byte) rgb.blue;
}
if (data.transparentPixel != -1) {
colorModel = new IndexColorModel(data.depth, rgbs.length, red, green, blue, data.transparentPixel);
} else {
colorModel = new IndexColorModel(data.depth, rgbs.length, red, green, blue);
}
BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null);
WritableRaster raster = bufferedImage.getRaster();
int[] pixelArray = new int[1];
for (int y = 0; y < data.height; y++) {
for (int x = 0; x < data.width; x++) {
int pixel = data.getPixel(x, y);
pixelArray[0] = pixel;
raster.setPixel(x, y, pixelArray);
}
}
return bufferedImage;
}
static ImageData convertToSWT(BufferedImage bufferedImage) {
if (bufferedImage.getColorModel() instanceof DirectColorModel) {
DirectColorModel colorModel = (DirectColorModel) bufferedImage.getColorModel();
PaletteData palette = new PaletteData(colorModel.getRedMask(), colorModel.getGreenMask(), colorModel.getBlueMask());
ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette);
WritableRaster raster = bufferedImage.getRaster();
int[] pixelArray = new int[3];
for (int y = 0; y < data.height; y++) {
for (int x = 0; x < data.width; x++) {
raster.getPixel(x, y, pixelArray);
int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2]));
data.setPixel(x, y, pixel);
}
}
return data;
} else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
IndexColorModel colorModel = (IndexColorModel) bufferedImage.getColorModel();
int size = colorModel.getMapSize();
byte[] reds = new byte[size];
byte[] greens = new byte[size];
byte[] blues = new byte[size];
colorModel.getReds(reds);
colorModel.getGreens(greens);
colorModel.getBlues(blues);
RGB[] rgbs = new RGB[size];
for (int i = 0; i < rgbs.length; i++) {
rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
}
PaletteData palette = new PaletteData(rgbs);
ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette);
data.transparentPixel = colorModel.getTransparentPixel();
WritableRaster raster = bufferedImage.getRaster();
int[] pixelArray = new int[1];
for (int y = 0; y < data.height; y++) {
for (int x = 0; x < data.width; x++) {
raster.getPixel(x, y, pixelArray);
data.setPixel(x, y, pixelArray[0]);
}
}
return data;
}
return null;
}
public static final ImageData createSampleImage(Display display) {
Image image = new Image(display, 100, 100);
Rectangle bounds = image.getBounds();
GC gc = new GC(image);
gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
gc.fillRectangle(bounds);
gc.setBackground(display.getSystemColor(SWT.COLOR_GREEN));
gc.fillOval(0, 0, bounds.width, bounds.height);
gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
gc.drawLine(0, 0, bounds.width, bounds.height);
gc.drawLine(bounds.width, 0, 0, bounds.height);
gc.dispose();
ImageData data = image.getImageData();
image.dispose();
return data;
}
}