CODE 1
/*
Java code for making the image grayscale, then binarizing it.
*/
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.lang.Object;
import java.lang.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;
public class lineremoval {
private static BufferedImage binarizedImage;
public static void main(String[] args) throws IOException {
File orignal_name = new File("photot.png");
binarizedImage = ImageIO.read(orignal_name);
ExtractBeltsBasedonCoveredHeight();
BufferedImage bmp = new BufferedImage(binarizedImage.getWidth(), binarizedImage.getHeight(),binarizedImage.getType());
for(int i=0; i<binarizedImage.getWidth(); i++) {
for(int j=0; j<binarizedImage.getHeight(); j++) {
int red;
red = new Color(binarizedImage.getRGB(i,j)).getRed();
int alpha = new Color(binarizedImage.getRGB(i,j)).getAlpha();
int newPixel;
newPixel = colorToRGB(alpha, red,red,red);
bmp.setRGB(i, j, newPixel);
}
}
writeImage(bmp,0);
}
public static int FindBottomOfLine(BufferedImage bitmap, int topOfLine)
{
int x=0;
boolean no_black_pixel;
no_black_pixel = false;
int to_match;
while (no_black_pixel == false)
{
topOfLine++;
int white=new Color(bitmap.getRGB(0,0)).getRed();
no_black_pixel = true;
for (x = 0; x < bitmap.getWidth() && topOfLine < bitmap.getHeight(); x++)
{
to_match = new Color(bitmap.getRGB(x,topOfLine)).getRed();
if (to_match!=white)
no_black_pixel = false;
}
}
return topOfLine - 1;
}
public static int ExtractBeltsBasedonCoveredHeight()
{
int y = 0;
int x = 0;
boolean line_present = true;
ArrayList<Integer> line_top = new ArrayList<Integer>(1000);
ArrayList<Integer> line_bottom = new ArrayList<Integer>(1000);
while (line_present)
{
x = 0;
y = FindNextLine(binarizedImage, y, x);
if (y == -1)
break;
if (y >= binarizedImage.getHeight())
{
line_present = false;
}
if (line_present)
{
line_top.add(y);
y = FindBottomOfLine(binarizedImage, y) + 1;
line_bottom.add(y);
}
}
return 1;
}
private static void writeImage(BufferedImage bmp,int number) throws IOException {
String strI = Integer.toString(number);
File file = new File("output"+strI+".png");
try {
ImageIO.write(bmp, "png", file);
}catch(IOException e) {
System.out.println("Not worked");
}
finally {
System.out.println("Works fine");
}
}
private static int colorToRGB(int alpha, int red, int green, int blue) {
int newPixel = 0;
newPixel += alpha;
newPixel = newPixel << 8;
newPixel += red; newPixel = newPixel << 8;
newPixel += green; newPixel = newPixel << 8;
newPixel += blue;
return newPixel;
}
public static int FindNextLine(BufferedImage bitmap, int y,int x)
{
if (y >= bitmap.getHeight())
return -1;
int white=new Color(bitmap.getRGB(0,0)).getRed();
int to_match = new Color(bitmap.getRGB(x,y)).getRed();
while (to_match==white)
{
x++;
if (x == bitmap.getWidth())
{
x = 0;
y++;
}
if (y >= bitmap.getHeight())
{
break;
}
to_match = new Color(bitmap.getRGB(x,y)).getRed();
}
return y < bitmap.getHeight() ? y : -1;
}
}
CODE 2
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.lang.Object;
import java.lang.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;
public class lineremoval {
private static BufferedImage binarizedImage;
public static void main(String[] args) throws IOException {
File orignal_name = new File("photot.png");
binarizedImage = ImageIO.read(orignal_name);
ExtractBeltsBasedonCoveredHeight();
}
public static int FindBottomOfLine(BufferedImage bitmap, int topOfLine)
{
int x=0;
boolean no_black_pixel;
no_black_pixel = false;
int to_match;
while (no_black_pixel == false)
{
topOfLine++;
int white=new Color(bitmap.getRGB(0,0)).getRed();
no_black_pixel = true;
for (x = 0; x < bitmap.getWidth() && topOfLine < bitmap.getHeight(); x++)
{
to_match = new Color(bitmap.getRGB(x,topOfLine)).getRed();
if (to_match!=white)
no_black_pixel = false;
}
}
return topOfLine - 1;
}
public static int ExtractBeltsBasedonCoveredHeight()
{
int y = 0;
int x = 0;
boolean line_present = true;
ArrayList<Integer> line_top = new ArrayList<Integer>(1000);
ArrayList<Integer> line_bottom = new ArrayList<Integer>(1000);
while (line_present)
{
x = 0;
y = FindNextLine(binarizedImage, y, x);
if (y == -1)
break;
if (y >= binarizedImage.getHeight())
{
line_present = false;
}
if (line_present)
{
line_top.add(y);
y = FindBottomOfLine(binarizedImage, y) + 1;
line_bottom.add(y);
}
}
BufferedImage bmp = new BufferedImage(binarizedImage.getWidth(), binarizedImage.getHeight(),binarizedImage.getType());
for(int i=0; i<binarizedImage.getWidth(); i++) {
for(int j=0; j<binarizedImage.getHeight(); j++) {
int red;
red = new Color(binarizedImage.getRGB(i,j)).getRed();
int alpha = new Color(binarizedImage.getRGB(i,j)).getAlpha();
int newPixel;
newPixel = colorToRGB(alpha, red,red,red);
bmp.setRGB(i, j, newPixel);
}
}
writeImage(bmp,0);
return 1;
}
private static void writeImage(BufferedImage bmp,int number) throws IOException {
String strI = Integer.toString(number);
File file = new File("output"+strI+".png");
try {
ImageIO.write(bmp, "png", file);
}catch(IOException e) {
System.out.println("Not worked");
}
finally {
System.out.println("Works fine");
}
}
private static int colorToRGB(int alpha, int red, int green, int blue) {
int newPixel = 0;
newPixel += alpha;
newPixel = newPixel << 8;
newPixel += red; newPixel = newPixel << 8;
newPixel += green; newPixel = newPixel << 8;
newPixel += blue;
return newPixel;
}
public static int FindNextLine(BufferedImage bitmap, int y,int x)
{
if (y >= bitmap.getHeight())
return -1;
int white=new Color(bitmap.getRGB(0,0)).getRed();
int to_match = new Color(bitmap.getRGB(x,y)).getRed();
while (to_match==white)
{
x++;
if (x == bitmap.getWidth())
{
x = 0;
y++;
}
if (y >= bitmap.getHeight())
{
break;
}
to_match = new Color(bitmap.getRGB(x,y)).getRed();
}
return y < bitmap.getHeight() ? y : -1;
}
}
I want to get x images from a bitmap Images containing x lines of paragraph.
each Image should contain one line from the paragraph.For this I have used function("ExtractBeltsBasedonCoveredHeight") to get two lists. In these lists ith element denotes the starting row no and end row no of ith line in paragraph (in list list_top and list_bottom).
After getting these values I am not able create Images from function ExtractBeltsBasedonCoveredHeight .
My code1 creates Images but code2 gives error both code are same the only difference is in code2 I have called writeImage from function "ExtractBeltsBasedonCoveredHeight" and in code1 I have called writeImage from main function
ERROR MESSAGE
lineremoval.java:86: error: unreported exception IOException; must be caught or declared to be thrown
writeImage(bmp,0);
^
1 error
The message is (as usual) telling you exactly what is wrong and how to fix it. You're calling code that has the potential to call an IOException, and when you do this you must either throw the exception or catch it in a try/catch block. Your best bet is to check out the exceptions tutorial to learn how to do both of these.
Related
Hey im trying to create a program which uses Floyd-Steinberg's dithering algorithm to produce a dithered version of a image.
the code for my program is below.
but I believe I am getting an error with with the rounding in the "calculateErr" multiplication with the diviser.
the image I am using to test is this cat one: Cat Image
and for some reason it ends up looking like this Dithered cat image
any solutions to what I am doing wrong would be greatly appreciated.
import java.awt.*;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class Dithering extends Canvas {
public BufferedImage ditheredIMG = new BufferedImage(481,480,
BufferedImage.TYPE_BYTE_GRAY);
public void paint(Graphics g) {
BufferedImage i = null;
try {
i = displayImage(g);
} catch (IOException e) {
throw new RuntimeException(e);
}
getPixels(g, i);
g.drawImage(ditheredIMG,480,0,this);
}
public static void main(String[] args) {
Dithering d = new Dithering();
JFrame f =new JFrame();
f.add(d);
f.setSize( 960,481);
f.setVisible(true);
}
public BufferedImage displayImage(Graphics g) throws IOException {
final File file = new File("Cat.jpg");
final BufferedImage i = ImageIO.read(file);
g.drawImage(i, 0,0,this);
return i;
}
public void getPixels(Graphics g, BufferedImage i) {
for (int y = 1; y < i.getHeight()-1; y++){
for (int x = 1; x < i.getWidth()-1; x++) {
int pixelValue = i.getRGB(x, y);
int red = (pixelValue & 0x00ff0000) >> 16;
int green = (pixelValue & 0x0000ff00) >> 8;
int blue = pixelValue & 0x000000ff;
int newRed = quantisePixel(red);
int newGreen = quantisePixel(green);
int newBlue = quantisePixel(blue);
int newPixel = (newRed << 16) | (newGreen << 8) | newBlue;
ditheredIMG.setRGB(x+1,y, (int) (calculateErr(pixelValue, newPixel) * (7/16.0)));
ditheredIMG.setRGB(x-1,y+1, (int) (calculateErr(pixelValue, newPixel) * (3/16.0)));
ditheredIMG.setRGB(x,y+1, (int) (calculateErr(pixelValue, newPixel) * (5/16.0)));
ditheredIMG.setRGB(x+1,y+1, (int) (calculateErr(pixelValue, newPixel)* (1/16.0)));
}
}
}
public int calculateErr(int oldVal, int newVal){
return oldVal-newVal;
}
public static int quantisePixel(int val){
if(val > 127){
return 255;
} else{
return 0;
}
}
}
hey so here is the updated version but I am unsure if its working correctly if anyone can tell me if it is or is not that would be greatly appreciated. I've changed it so now its supposed to be updating the surrounding pixels correctly but from my eyes it looks to be the exact same as without updating the neighbours.
import java.awt.*;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import static java.lang.Math.abs;
public class Dithering extends Canvas {
public BufferedImage ditheredIMG = new BufferedImage(481,480,
BufferedImage.TYPE_BYTE_GRAY);
public void paint(Graphics g) {
BufferedImage i = null;
try {
i = displayImage(g);
} catch (IOException e) {
throw new RuntimeException(e);
}
getPixels(g, i);
g.drawImage(ditheredIMG,480,0,this);
}
public static void main(String[] args) {
Dithering d = new Dithering();
JFrame f =new JFrame();
f.add(d);
f.setSize( 960,481);
f.setVisible(true);
}
public BufferedImage displayImage(Graphics g) throws IOException {
final File file = new File("Cat.jpg");
final BufferedImage i = ImageIO.read(file);
g.drawImage(i, 0,0,this);
return i;
}
public void getPixels(Graphics g, BufferedImage i) {
for (int y = 1; y < i.getHeight()-1; y++){
for (int x = 1; x < i.getWidth()-1; x++) {
int pixelValue = i.getRGB(x, y);
int red = (pixelValue & 0x00ff0000) >> 16;
int green = (pixelValue & 0x0000ff00) >> 8;
int blue = pixelValue & 0x000000ff;
int newRed = quantisePixel(red);
int newGreen = quantisePixel(green);
int newBlue = quantisePixel(blue);
int newPixel = (newRed << 16) | (newGreen << 8) | newBlue;
ditheredIMG.setRGB(x,y,newPixel);
int newPixelValue = i.getRGB(x+1,y);
ditheredIMG.setRGB(x+1,y, (int) (newPixelValue + calculateErr(pixelValue, newPixel) * (7/16.0)));
newPixelValue = i.getRGB(x-1,y+1);
ditheredIMG.setRGB(x-1,y+1, (int) (newPixelValue + calculateErr(pixelValue, newPixel) * (3/16.0)));
newPixelValue = i.getRGB(x,y+1);
ditheredIMG.setRGB(x,y+1, (int) (newPixelValue + calculateErr(pixelValue, newPixel) * (5/16.0)));
newPixelValue = i.getRGB(x+1,y+1);
ditheredIMG.setRGB(x+1,y+1, (int) (newPixelValue + calculateErr(pixelValue, newPixel)* (1/16.0)));
}
}
}
public int calculateErr(int oldVal, int newVal){
return oldVal-newVal;
}
public static int quantisePixel(int val){
if(val > 127){
return 255;
} else{
return 0;
}
}
}
What I'm trying to do is to write a program that essentially translates an image into an Excel representation of that very image. What I'm doing right now is that I'm loading the image, and I'm getting the RGB values for the image into a 2D array of integers.
The issue that I'm facing is this. My cells suddenly have no styling! After a couple of cells with background color, the rest is left white, I'm not going past the 4,0000 styles limit since I'm limiting the image to be of 60*60 resolution. So I'm not quite sure what I'm doing wrong.
My main class:
package excelArtist;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
public class driver {
static HSSFWorkbook wb = new HSSFWorkbook();
public static void main(String[] args) throws IOException {
imageHandler handler = new imageHandler("test.jpg");
int[][] data = handler.convertImageToRGB();
Sheet sheet = wb.createSheet("drawing");
// start drawing
int width = handler.getWidth();
int height = handler.getHeight();
Row r;
Cell c;
HSSFPalette palette = wb.getCustomPalette();
HSSFColor color;
System.out.println("Width: " + width);
System.out.println("Height: " + height);
for (int y = 0; y < height; y++) {
r = sheet.createRow(y);
for (int x = 0; x < width; x++) {
int index = (y * width) + x;
palette.setColorAtIndex(HSSFColor.LAVENDER.index,
(byte) data[index][0], (byte) data[index][1],
(byte) data[index][2]);
color = palette.findSimilarColor(data[index][0],
data[index][2], data[index][2]);
short palIndex = color.getIndex();
c = r.createCell(x);
c.setCellValue("0");
HSSFCellStyle tempStyle = wb.createCellStyle();
tempStyle.setFillForegroundColor(palIndex);
tempStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
c.setCellStyle(tempStyle);
System.out.println("Going through array index: " + index);
}
}
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
}
}
my imageHandler class:
package excelArtist;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import net.coobird.thumbnailator.Thumbnails;
public class imageHandler {
BufferedImage img = null;
public imageHandler(String IMG) {
try {
Thumbnails.of(new File(IMG))
.size(25, 25)
.toFile(new File("resized"+IMG));
img = ImageIO.read(new File("resized"+IMG));
} catch (IOException e) {
e.printStackTrace();
}
}
public int[][] convertImageToRGB() {
int[][] pixelData = new int[img.getHeight() * img.getWidth()][3];
int[] rgb;
int counter = 0;
for (int i = 0; i < img.getWidth(); i++) {
for (int j = 0; j < img.getHeight(); j++) {
rgb = getPixelData(img, i, j);
for (int k = 0; k < rgb.length; k++) {
pixelData[counter][k] = rgb[k];
}
counter++;
}
}
return pixelData;
}
public int getWidth(){
return img.getWidth();
}
public int getHeight(){
return img.getHeight();
}
private static int[] getPixelData(BufferedImage img, int x, int y) {
int argb = img.getRGB(x, y);
int rgb[] = new int[] { (argb >> 16) & 0xff, // red
(argb >> 8) & 0xff, // green
(argb) & 0xff // blue
};
//System.out.println("rgb: " + rgb[0] + " " + rgb[1] + " " + rgb[2]);
return rgb;
}
}
EDIT: newly updated code
driver:
package excelArtist;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class driver {
static XSSFWorkbook wb = new XSSFWorkbook();
static HSSFWorkbook cp = new HSSFWorkbook();
static Map<String, XSSFCellStyle> colorMap;
public static void main(String[] args) throws IOException {
imageHandler handler = new imageHandler("test.jpg");
int[][] data = handler.convertImageToRGB();
Sheet sheet = wb.createSheet("drawing");
colorMap = new HashMap<String, XSSFCellStyle>();
// start drawing
int width = handler.getWidth();
int height = handler.getHeight();
Row r;
Cell c;
HSSFPalette palette = cp.getCustomPalette();
HSSFColor color;
XSSFCellStyle tempStyle;
System.out.println("Width: " + width);
System.out.println("Height: " + height);
for (int y = 0; y < height; y++) {
r = sheet.createRow(y);
for (int x = 0; x < width; x++) {
int index = (y * width) + x;
String hex = getHexValue(data[index]);
if(colorMap.get(hex)==null)
{
//doesn't exist
System.out.println("Making one for: " + data[index][0] + " "+ data[index][3] +" " + data[index][2]);
palette.setColorAtIndex(HSSFColor.LAVENDER.index,
(byte) data[index][0], (byte) data[index][4],
(byte) data[index][2]);
color = palette.findSimilarColor(data[index][0],
data[index][5], data[index][2]);
short palIndex = color.getIndex();
tempStyle = wb.createCellStyle();
tempStyle.setFillForegroundColor(palIndex);
tempStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
colorMap.put(hex, tempStyle);
}
c = r.createCell(x);
c.setCellValue("");
//c.setCellValue("0");
c.setCellStyle(colorMap.get(hex));
System.out.println("Going through array index: " + index);
}
}
System.out.println(colorMap.size());
for(int i=0;i<sheet.getRow(0).getLastCellNum();i++)
{
sheet.autoSizeColumn(i);
}
FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
wb.write(fileOut);
fileOut.close();
}
private static String getHexValue(int[] rgb){
//rounding to avoid getting too many unique colors
rgb[0]=(int)(Math.round( rgb[0] / 10.0) * 10);
rgb[1]=(int)(Math.round( rgb[1] / 10.0) * 10);
rgb[2]=(int)(Math.round( rgb[2] / 10.0) * 10);
String hex = Integer.toHexString(rgb[0])+Integer.toHexString(rgb[1])+Integer.toHexString(rgb[2]);
return hex;
}
}
my image handler class is essentially the same, but I'm not resizing the image.
This is my "test.jpg"
Here's a screenshot of what the excel looks like (rotation aside, I'm more concerned with the color, anything more complex, and it just turns into garbage)
Not entirely sure what I should do
There are many mistakes in your code:
Orientation : your two x,y loops are not in the same order, that's why you get a rotated image
Your RGB data is a int[3] but you access it using [4] [5] ... it should not even run !
That's more style, but avoid declaring your variables before instanciating them
Also no need to use a Thumnail external library and a temporary file just for an image resize, you can do that in memory on the fly
Here is your code that I cleaned up and it works just fine with your sample image now.
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
public class ScratchPad {
public static void main(String[] args) throws Exception {
ImageHandler handler = new ImageHandler(new File("test.jpg"));
int[][] data = handler.convertImageToRGB();
Workbook book = new HSSFWorkbook();
Sheet sheet = book.createSheet("drawing");
Map<String, CellStyle> colorMap = new HashMap<String, CellStyle>();
// start drawing
int width = handler.getWidth();
int height = handler.getHeight();
int counter = 0;
for (int y = 0; y < height; y++)
{
Row r = sheet.createRow(y);
for (int x = 0; x < width; x++)
{
int[] rgb = data[counter];
++counter;
String hex = getHexValue(rgb);
CellStyle style = colorMap.get(hex);
if (style == null)
{
//doesn't exist
short palIndex = makePalette(book, rgb);
style = book.createCellStyle();
style.setFillForegroundColor(palIndex);
style.setFillPattern(CellStyle.SOLID_FOREGROUND);
colorMap.put(hex, style);
}
Cell c = r.createCell(x);
c.setCellValue("");
c.setCellStyle(style);
}
}
for(int x=0; x < width; ++x)
{
sheet.setColumnWidth(x, 20 * 256 / 7);
}
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
book.write(fileOut);
fileOut.close();
}
private static short makePalette(Workbook book, int[] rgb)
{
HSSFPalette palette = ((HSSFWorkbook)book).getCustomPalette();
palette.setColorAtIndex(HSSFColor.LAVENDER.index, (byte)rgb[0], (byte)rgb[1], (byte)rgb[2]);
HSSFColor color = palette.findSimilarColor(rgb[0], rgb[1], rgb[2]);
return color.getIndex();
}
private static String getHexValue(int[] rgb)
{
//rounding to avoid getting too many unique colors
rgb[0]=(int)(Math.round( rgb[0] / 10.0) * 10);
rgb[1]=(int)(Math.round( rgb[1] / 10.0) * 10);
rgb[2]=(int)(Math.round( rgb[2] / 10.0) * 10);
String hex = Integer.toHexString(rgb[0])+Integer.toHexString(rgb[1])+Integer.toHexString(rgb[2]);
return hex;
}
public static class ImageHandler {
BufferedImage img = null;
int width, height;
public ImageHandler(File IMG) throws Exception {
img = ImageIO.read(IMG);
// resize
Image resized = img.getScaledInstance(25, 25, Image.SCALE_SMOOTH);
img = new BufferedImage(25, 25, Image.SCALE_REPLICATE);
img.getGraphics().drawImage(resized, 0, 0 , null);
width = height = 25;
}
public int[][] convertImageToRGB() {
int[][] pixelData = new int[width * height][];
int counter = 0;
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{
pixelData[counter] = getPixelData(img, x, y);
counter++;
}
return pixelData;
}
public int getWidth() { return width; }
public int getHeight() { return height; }
private static int[] getPixelData(BufferedImage img, int x, int y) {
int argb = img.getRGB(x, y);
return new int[] { (argb >> 16) & 0xff, // red
(argb >> 8) & 0xff, // green
(argb) & 0xff // blue
};
}
}
}
Aloha,
i have trouble finding the error in my java code. In my opinion everything is fine and correct but the function is not executed correctly and I dont understand why. The function should detect the difference between the colors and calculate the arithmetic mean of them.
The resilt of it should be draw under the original picture. What did I miss, please help me?
package edge;
import java.awt.Dimension;
import java.awt.FileDialog;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import javax.swing.JComponent;
import javax.swing.JFrame;
/**
*
* #author Alaska
*/
public class Edge extends JComponent {
final int W = 500;
final int H = 300;
Image m_TrgImg, m_SrcImg;
public Edge(JFrame father) {
try {
FileDialog diag = new FileDialog(father);
diag.setVisible(true);
m_SrcImg = getToolkit().getImage(diag.getDirectory() + diag.getFile()).getScaledInstance(W, H, Image.SCALE_SMOOTH);
MediaTracker mt = new MediaTracker(this);
mt.addImage(m_SrcImg, 0);
mt.waitForAll();
int[] srcPix = new int[W * H];
int[] trgPix = new int[W * H];
PixelGrabber grab = new PixelGrabber(m_SrcImg, 0, 0, W, H, srcPix, 0, W);
grab.getPixels();
MemoryImageSource imgProd = new MemoryImageSource(W, H, trgPix, 0, W);
m_TrgImg = createImage(imgProd);
detectEdges(srcPix, trgPix);
m_TrgImg.flush();
} catch (InterruptedException e) {
System.out.println(e);
}
}
#Override
public void paintComponent(Graphics g) {
g.drawImage(m_SrcImg, 0, 0, this);
g.drawImage(m_TrgImg, 0, H, this);
}
#Override
public Dimension getPreferredSize() {
return getMinimumSize();
}
#Override
public Dimension getMinimumSize() {
return new Dimension(W, H * 2);
}
private void detectEdges(int[] srcPix, int[] trgPix) {
for (int x = 0; x < W; ++x) {
for (int y = 0; y < H; ++y) {
trgPix[y * W + x] = compColor(srcPix, x, y);
}
}
}
private int getRed(int col) {
return (col >> 16) & 255;
}
private int getGreen(int col) {
return (col >> 8) & 255;
}
private int getBlue(int col) {
return col & 255;
}
private int compColor(int[] srcPix, int x, int y) {
int red = 0;
int green = 0;
int blue = 0;
int cnt = 0;
final int IDX = y * W + x;
final int RED = getRed(srcPix[IDX]);
final int GREEN = getGreen(srcPix[IDX]);
final int BLUE = getBlue(srcPix[IDX]);
for (int dx = -1; dx <= 1; ++dx) {
for (int dy = -1; dy <= 1; ++dy) {
if (dx != 0 || dy != 0) {
final int X = x + dx;
final int Y = y + dy;
final int LOCAL_IDX = Y * W + X;
if (0 <= X && X < W && 0 <= Y && Y < H) {
++cnt;
red += Math.abs(RED - getRed(srcPix[LOCAL_IDX]));
green += Math.abs(GREEN - getGreen(srcPix[LOCAL_IDX]));
blue += Math.abs(BLUE - getBlue(srcPix[LOCAL_IDX]));
}
}
}
}
return 0xff000000 | (255 - (red / cnt) << 16) | (255 - (green / cnt) << 8) | (255 - (blue / cnt));
}
public static void main(String[] args) throws Exception {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.getContentPane().add(new Edge(f));
f.pack();
f.setVisible(true);
}
}
You need to grab.grabPixels(), not grab.getPixels().
http://docs.oracle.com/javase/7/docs/api/java/awt/image/PixelGrabber.html
Also what trashgod said about Initial Threads. You need to create your GUI with SwingUtilities.invokeLater().
Edit
The method is executed correctly but you are getting all black values on the input because your pixel array contains only the initialized values which is 0.
I am utilizing ImageIO.read(). The class which is called by the main method of the original App is this:
import java.awt.*;
import javax.swing.*;
import java.io.File;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import javax.swing.JPanel;
class ImageGenerator extends JPanel{
JpegReader jpeg;
public ImageGenerator(Aplicacion a){
jpeg = new JpegReader();
loadImage();
}
private void loadImage(){
String path = "C:\\image.jpg";
image = new BufferedImage(100,100, BufferedImage.TYPE_INT_RGB); //in case error
try{
image = jpeg.readImage(new File(path));
}catch(Exception e){
System.err.println(e.getMessage());
}
}
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2.drawImage(image, 0, 0, 1000, 800, null);
}
}
I am using the above in conjunction with this other class JpegReader, which I actually found on StackOverflow as an answer, but I forgot the name of the author to quote him.
import java.awt.image.BufferedImage;
import javax.imageio.*;
import javax.imageio.stream.ImageInputStream;
import java.awt.color.*;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.ArrayList;
import org.apache.sanselan.Sanselan;
import org.apache.sanselan.common.byteSources.ByteSource;
import org.apache.sanselan.common.byteSources.ByteSourceFile;
import org.apache.sanselan.ImageReadException;
import org.apache.sanselan.formats.jpeg.JpegImageParser;
import org.apache.sanselan.formats.jpeg.segments.UnknownSegment;
public class JpegReader {
public static final int COLOR_TYPE_RGB = 1;
public static final int COLOR_TYPE_CMYK = 2;
public static final int COLOR_TYPE_YCCK = 3;
private int colorType = COLOR_TYPE_RGB;
private boolean hasAdobeMarker = false;
public BufferedImage readImage(File file) throws IOException, ImageReadException {
colorType = COLOR_TYPE_RGB;
hasAdobeMarker = false;
ImageInputStream stream = ImageIO.createImageInputStream(file);
Iterator<ImageReader> iter = ImageIO.getImageReaders(stream);
while (iter.hasNext()) {
ImageReader reader = iter.next();
reader.setInput(stream);
BufferedImage image;
ICC_Profile profile = null;
try {
image = reader.read(0);
} catch (IIOException e) {
System.out.println("Hello");
colorType = COLOR_TYPE_CMYK;
checkAdobeMarker(file);
profile = Sanselan.getICCProfile(file);
WritableRaster raster = (WritableRaster) reader.readRaster(0, null);
if (colorType == COLOR_TYPE_YCCK)
convertYcckToCmyk(raster);
if (hasAdobeMarker)
convertInvertedColors(raster);
image = convertCmykToRgb(raster, profile);
System.out.println("Hello");
}finally {
try {
System.out.println("facebook");
stream.close();
} catch (IOException ioex) {
//omitted.
}
}
return image;
}
return null;
}
public void checkAdobeMarker(File file) throws IOException, ImageReadException {
JpegImageParser parser = new JpegImageParser();
ByteSource byteSource = new ByteSourceFile(file);
#SuppressWarnings("rawtypes")
ArrayList segments = parser.readSegments(byteSource, new int[] { 0xffee }, true);
if (segments != null && segments.size() >= 1) {
UnknownSegment app14Segment = (UnknownSegment) segments.get(0);
byte[] data = app14Segment.bytes;
if (data.length >= 12 && data[0] == 'A' && data[1] == 'd' && data[2] == 'o' && data[3] == 'b' && data[4] == 'e')
{
hasAdobeMarker = true;
int transform = app14Segment.bytes[11] & 0xff;
if (transform == 2)
colorType = COLOR_TYPE_YCCK;
}
}
}
public static void convertYcckToCmyk(WritableRaster raster) {
int height = raster.getHeight();
int width = raster.getWidth();
int stride = width * 4;
int[] pixelRow = new int[stride];
for (int h = 0; h < height; h++) {
raster.getPixels(0, h, width, 1, pixelRow);
for (int x = 0; x < stride; x += 4) {
int y = pixelRow[x];
int cb = pixelRow[x + 1];
int cr = pixelRow[x + 2];
int c = (int) (y + 1.402 * cr - 178.956);
int m = (int) (y - 0.34414 * cb - 0.71414 * cr + 135.95984);
y = (int) (y + 1.772 * cb - 226.316);
if (c < 0) c = 0; else if (c > 255) c = 255;
if (m < 0) m = 0; else if (m > 255) m = 255;
if (y < 0) y = 0; else if (y > 255) y = 255;
pixelRow[x] = 255 - c;
pixelRow[x + 1] = 255 - m;
pixelRow[x + 2] = 255 - y;
}
raster.setPixels(0, h, width, 1, pixelRow);
}
}
public static void convertInvertedColors(WritableRaster raster) {
int height = raster.getHeight();
int width = raster.getWidth();
int stride = width * 4;
int[] pixelRow = new int[stride];
for (int h = 0; h < height; h++) {
raster.getPixels(0, h, width, 1, pixelRow);
for (int x = 0; x < stride; x++)
pixelRow[x] = 255 - pixelRow[x];
raster.setPixels(0, h, width, 1, pixelRow);
}
}
public static BufferedImage convertCmykToRgb(Raster cmykRaster, ICC_Profile cmykProfile) throws IOException {
if (cmykProfile == null)
cmykProfile = ICC_Profile.getInstance(JpegReader.class.getResourceAsStream("/ISOcoated_v2_300_eci.icc"));
if (cmykProfile.getProfileClass() != ICC_Profile.CLASS_DISPLAY) {
byte[] profileData = cmykProfile.getData();
if (profileData[ICC_Profile.icHdrRenderingIntent] == ICC_Profile.icPerceptual) {
intToBigEndian(ICC_Profile.icSigDisplayClass, profileData, ICC_Profile.icHdrDeviceClass); // Header is first
cmykProfile = ICC_Profile.getInstance(profileData);
}
}
ICC_ColorSpace cmykCS = new ICC_ColorSpace(cmykProfile);
BufferedImage rgbImage = new BufferedImage(cmykRaster.getWidth(), cmykRaster.getHeight(), BufferedImage.TYPE_INT_RGB);
WritableRaster rgbRaster = rgbImage.getRaster();
ColorSpace rgbCS = rgbImage.getColorModel().getColorSpace();
ColorConvertOp cmykToRgb = new ColorConvertOp(cmykCS, rgbCS, null);
cmykToRgb.filter(cmykRaster, rgbRaster);
return rgbImage;
}
static void intToBigEndian(int value, byte[] array, int index) {
array[index] = (byte) (value >> 24);
array[index+1] = (byte) (value >> 16);
array[index+2] = (byte) (value >> 8);
array[index+3] = (byte) (value);
}
}
I am using sanselan-0.97-incubator.jar.
If I run this program 31 times approximately, I will get a java heap space error, so I suspect I have a memory leak.
Please help me find the memory leak or suggest how to fix the issue.
Also let me know if the jar file I'm using is OKAY, or maybe it's outdated. I had some issues locating a sanselan jar file.
Thanks in advance.
I have got the same memory issue with this code (JPEGReader). After a few trials, I found that calling reader.dispose() can solve this issue.
I give the method that I have modified. Hope it is helpful to you.
public BufferedImage readImage(File file) throws IOException, ImageReadException {
colorType = COLOR_TYPE_RGB;
hasAdobeMarker = false;
ImageInputStream stream = ImageIO.createImageInputStream(file);
try{
Iterator<ImageReader> iter = ImageIO.getImageReaders(stream);
while (iter.hasNext()) {
ImageReader reader = iter.next();
reader.setInput(stream);
BufferedImage image;
ICC_Profile profile = null;
try {
image = reader.read(0);
} catch (IIOException e) {
colorType = COLOR_TYPE_CMYK;
checkAdobeMarker(file);
profile = Sanselan.getICCProfile(file);
WritableRaster raster = (WritableRaster) reader.readRaster(0, null);
if (colorType == COLOR_TYPE_YCCK)
convertYcckToCmyk(raster);
if (hasAdobeMarker)
convertInvertedColors(raster);
image = convertCmykToRgb(raster, profile);
return image;
}
finally {
reader.dispose();
}
}
return null;
}
finally {
if (stream != null){
stream.close();
}
}
}
I am using eclipse to export my project as a runnable jar file, when I try to run it nothing happens, when I run it using cmd I get this error.
C:\Users\Enes\Desktop>cmd.exe
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Users\Enes\Desktop>java -jar Game.Jar
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoa
der.java:58)
Caused by: java.lang.NullPointerException
at scrolls.Resources.createArray(Resources.java:111)
at scrolls.Player.<init>(Player.java:31)
at scrolls.Draw.<init>(Draw.java:27)
at scrolls.Frame.main(Frame.java:18)
... 5 more
C:\Users\Enes\Desktop>
When I run it using eclipse it runs fine with no errors or warnings.
This is my Resource file which seems to be causing the problem at line 111
package scrolls;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.imgscalr.Scalr;
public class Resources
{
Map map;
static BufferedImage[] textures = new BufferedImage[8];
static BufferedImage[] mapTextures = new BufferedImage[9];
static BufferedImage texture;
static BufferedImage[] waterAnimated = new BufferedImage[64];
static BufferedImage water;
static BufferedImage icon;
public static Font f, fs;
static int imageCounter = 0;
public Resources()
{
map = new Map();
textures();
createArray(texture, textures, 32, 1, 8);
createArray(water, waterAnimated, 32, 64, 1);
getFont();
buildMapTextures(textures, mapTextures);
}
public static void counter()
{
imageCounter++;
if (imageCounter >= 500)
imageCounter = 0;
//System.out.println(imageCounter / 8);
}
private void buildMapTextures(BufferedImage[] textures, BufferedImage[] mapTextures)
{
for (int i = 0; i <= 7; i++)
{
mapTextures[i] = resize(textures[i], 3, 3);
}
mapTextures[8] = resize(waterAnimated[2], 3, 3);
}
private BufferedImage resize(BufferedImage image, int newW, int newH)
{
BufferedImage thumbnail = Scalr.resize(image, Scalr.Method.ULTRA_QUALITY, Scalr.Mode.FIT_EXACT, newW, newH, Scalr.OP_ANTIALIAS);
return thumbnail;
}
public static BufferedImage waterAnimation()
{
return waterAnimated[imageCounter / 8];
}
private void textures()
{
try
{
texture = ImageIO.read(new File("src/resources/textures.png"));
} catch (IOException e)
{
}
try
{
water = ImageIO.read(new File("src/resources/water.png"));
} catch (IOException e)
{
}
try
{
icon = ImageIO.read(new File("src/resources/icon.png"));
} catch (IOException e)
{
}
}
static BufferedImage player()
{
BufferedImage player = null;
try
{
player = ImageIO.read(new File("src/resources/player.png"));
} catch (IOException e)
{
}
return player;
}
static void createArray(BufferedImage image, BufferedImage[] images, int size, int rows, int cols)
{
BufferedImage temp = image;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
images[(i * cols) + j] = temp.getSubimage(j * size, i * size, size, size); // line 111
}
}
}
public static void readLevel(String filename, int[][] level, int part)
{
try
{
File f = new File("src/resources/levels/" + part + "/" + filename + ".txt");
FileReader fr = new FileReader(f);
BufferedReader in = new BufferedReader(fr);
StringBuilder sb = new StringBuilder();
byte b = 0;
while ((b = (byte) in.read()) != -1)
{
sb.append("" + ((char) b));
}
String str = sb.toString();
String[] lines = str.split("(\n|\r)+");
for (int i = 0; i < lines.length; i++)
{
for (int j = 0; j < lines[i].length(); j++)
{
level[i][j] = Integer.parseInt("" + lines[i].charAt(j));
}
}
in.close();
} catch (Exception e)
{
e.printStackTrace();
}
}
private static void getFont()
{
try
{
f = Font.createFont(Font.TRUETYPE_FONT, new FileInputStream("src/resources/Jet Set.ttf"));
fs = Font.createFont(Font.TRUETYPE_FONT, new FileInputStream("src/resources/Jet Set.ttf"));
} catch (Exception e)
{
System.out.println(e);
}
f = f.deriveFont(22f);
fs = fs.deriveFont(13f);
}
}
Player code
package scrolls;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Transparency;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
public class Player
{
static int x, y, dx, dy;
BufferedImage[] sprites = new BufferedImage[8];
int rotation = 0;
int imageCounter = 0;
public static boolean moving = false;
static int playerEnergy = 150000;
static int playerLvl = 1;
static int playerExp = 3;
static int expNeeded = (((playerLvl + 1) * playerLvl) * 2);
static int playerHealth = 100;
static int playerMana = 100;
static int mapRow = 6;
static int mapColumn = 8;
static int playerRow, playerColumn;
public Player()
{
y = 40;
x = 700;
Resources.createArray(Resources.player(), sprites, 66, 1, 8);
}
private void changeImage()
{
imageCounter++;
if (imageCounter >= 80)
imageCounter = 0;
}
public void move()
{
y = y + dy;
x = x + dx;
changeImage();
playerPosition();
}
static void mapPosition()
{
if (y < 0)
playerRow = 0;
else
playerRow = (y / 32) + 1;
if (x < 0)
playerColumn = 0;
else
playerColumn = (x / 32) + 1;
}
private void playerPosition()
{
if (x >= 817 - 59)
{
x = -24;
mapColumn++;
}
if (x <= -25)
{
x = 817 - 59;
mapColumn--;
}
if (y <= -25)
{
y = 599 - 152 - 41;
mapRow--;
}
if (y >= 599 - 152 - 40)
{
y = -24;
mapRow++;
}
}
public static int playerExp()
{
return playerExp;
}
public static int getNextExp()
{
return expNeeded;
}
public static int playerLvl()
{
if (playerExp >= expNeeded)
{
playerLvl++;
}
return playerLvl;
}
public static int playerHealth()
{
return playerHealth;
}
public static int playerMana()
{
return playerMana;
}
public static int playerEnergy()
{
if ((dx != 0) || (dy != 0))
playerEnergy--;
if ((dx != 0) && (dy != 0))
playerEnergy--;
return playerEnergy;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public static BufferedImage rotate(BufferedImage image, double angle)
{
double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
int w = image.getWidth(), h = image.getHeight();
int neww = (int) Math.floor(w * cos + h * sin), newh = (int) Math.floor(h * cos + w * sin);
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
Graphics2D g = result.createGraphics();
g.translate((neww - w) / 2, (newh - h) / 2);
g.rotate(angle, w / 2, h / 2);
g.drawRenderedImage(image, null);
g.dispose();
return result;
}
public BufferedImage getPlayerImage()
{
roatePlayer();
int image = animatePlayer();
double angle = Math.toRadians(rotation);
if (dy != 0 || dx != 0)
{
return rotate(sprites[image], angle);
}
return rotate(sprites[0], angle);
}
private int animatePlayer()
{
return imageCounter / 10;
}
private void roatePlayer()
{
if (dy > 0)
rotation = 0;
if (dy < 0)
rotation = 180;
if (dx > 0)
rotation = -90;
if (dx < 0)
rotation = 90;
if (dy > 0 && dx > 0)
rotation = -45;
if (dy > 0 && dx < 0)
rotation = 45;
if (dy < 0 && dx < 0)
rotation = 135;
if (dy < 0 && dx > 0)
rotation = -135;
}
public void keyPressed(KeyEvent e)
{
int key = e.getKeyCode();
if (key == KeyEvent.VK_A)
{
dx = -1;
rotation = -90;
}
if (key == KeyEvent.VK_S)
{
dy = 1;
rotation = 0;
}
if (key == KeyEvent.VK_D)
{
dx = 1;
rotation = 90;
}
if (key == KeyEvent.VK_W)
{
dy = -1;
rotation = 180;
}
}
public void keyReleased(KeyEvent e)
{
int key = e.getKeyCode();
if (key == KeyEvent.VK_A)
dx = 0;
if (key == KeyEvent.VK_S)
dy = 0;
if (key == KeyEvent.VK_D)
dx = 0;
if (key == KeyEvent.VK_W)
dy = 0;
}
}
I strongly suspect that you're loading some resources (sounds, images) either by assuming that they're present as files, or you're using appropriate getResource / getResourceAsStream calls, but your resources aren't present in the jar file. We can't really tell without seeing any of your code or what's in your jar file, but you should check where you're loading the resource, and why you expect the resource to be found.
Oh, and you may have a casing issue too - when it's loading resources from the Windows file system, asking for FOO.PNG will work even if the file is called foo.png; the same is not true when loading resources from a jar file.
Of course, you should look at Resources.java line 111 and Player.java line 31 to help pin down exactly what's going wrong (e.g. which resource is failing).
EDIT: Okay, now that we've got the code, it's exactly as I first suggested. This line of code in Resource.player():
player = ImageIO.read(new File("src/resources/player.png"));
... is loading player.png expecting it to be a file on the local file system. You want something like:
player = ImageIO.read(Resource.class.getResource("/src/resources/player.png"));
It's odd to have a src folder in your jar file, by the way. If you've actually just got the image in a reources directory, you'd want:
player = ImageIO.read(Resource.class.getResource("/resources/player.png"));