Transformation of photo to photo in the form of matrix - java

I wrote the following code, but the photographs must be in the form of a matrix, not side by side.
My goal is not to leave any empty space at the end of the canvas.
import java.awt.Color;
public class aaa {
public static Color karstr ( Color x,Color y,double lambda ){
int r= (int)((1-lambda)*x.getRed()+lambda*y.getRed());
int g= (int)((1-lambda)*x.getGreen()+lambda*y.getGreen());
int b= (int)((1-lambda)*x.getBlue()+lambda*y.getBlue());
return new Color (r,g,b);
}
public static void main(String[] args) {
int genilik =50;
int ykseklik=100;
Picture p=new Picture("c:/data/a.jpg");
Picture q=new Picture("c:/data/b.jpg");
Picture r= new Picture(p.width()+400,p.height()+10);
for (int i = 0; i < p.width(); i++)
for (int j = 0; j < p.height(); j++) {
Color x=p.get(i, j);
Color y=q.get(i,j);
r.set(i*genilik/p.width(),j*ykseklik/p.height(), x);
Color c=karstr(x,y,(double)1/5);
r.set(i*genilik/p.width()+50,j*ykseklik/p.height(), c);
Color a=karstr(x,y,(double)1/4);
r.set(i*genilik/p.width()+100,j*ykseklik/p.height(),a);
Color b=karstr(x,y,(double)1/3);
r.set(i*genilik/p.width()+150,j*ykseklik/p.height(),b);
Color f=karstr(x,y,(double)1/2);
r.set(i*genilik/p.width()+200,j*ykseklik/p.height(),f);
Color g=karstr(x,y,(double)1/1.2);
r.set(i*genilik/p.width()+250,j*ykseklik/p.height(),g);
r.set(i*genilik/p.width()+300,j*ykseklik/p.height(), y);
}
r.show();
}
}

import java.awt.Color;
public class PhotoTransformation {
private Picture source;
private Picture dest;
public PhotoTransformation(Picture source, Picture dest) {
source = source;
dest = dest;
}
public static void main(String[] args) {
Picture p=new Picture("c:/data/a.jpg");
Picture q=new Picture("c:/data/b.jpg");
PhotoTransformation photoTransformation = new PhotoTransformation(p, q);
Picture[] photoSeries = photoTransformation.produceTransformationPhotos(8);
// Show the photos
}
public Picture[] produceTransformationPhotos(int transitionPhotoNumber) {
int photoNumber = transitionPhotoNumber + 2;
Picture[] photos = new Picture[photoNumber];
int width = source.width();
int height = source.height();
for (int p = 0; p < photoNumber; p++) {
Picture newPhoto = new Picture(width, height);
photos[p] = newPhoto;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
Color sourceColor = source.get(i, j);
Color destColor = dest.get(i, j);
double weight = (double) p / (double) (photoNumber - 1);
Color transformationColor = produceWeightedMeanColor(sourceColor, destColor, weight);
newPhoto.set(i, j, transformationColor);
}
}
}
return photos;
}
private static Color produceWeightedMeanColor(Color x, Color y, double weight) {
int r = (int)((1-weight) * x.getRed() + weight * y.getRed());
int g = (int)((1-weight) * x.getGreen() + weight * y.getGreen());
int b = (int)((1-weight) * x.getBlue() + weight * y.getBlue());
return new Color(r,g,b);
}
}

Related

Java - counting the occurrences of a character in a random generator method using a separate method

I'm trying to figure out how to count the number of stars that were printed last time the print() method was used.
I'm confused on how to take the value of starsInLastPrint variable into the starsInLastPrint() method. My understanding is that this isn't possible. I assume there are plenty of things wrong with my current code that isn't helping. Below is my current state as I am stuck.
import java.util.Random;
public class NightSky {
private double density;
private int width;
private int height;
private int starsInLastPrint;
public NightSky(double density) {
width = 20;
height = 10;
this.density = density;
}
public NightSky(int width, int height) {
density = 0.1;
this.width = width;
this.height = height;
}
public NightSky(double density, int width, int height) {
this.density = density;
this.width = width;
this.height = height;
}
public void printLine() {
Random starPlacement = new Random();
String[] stars = new String[(this.width)];
for (int i = 0; i < this.width; i++) {
double random = starPlacement.nextDouble();
if (random <= this.density) {
stars[i] = "*";
this.starsInLastPrint++;
} else {
stars[i] = " ";
}
}
int j = 0;
while (j < stars.length) {
System.out.print(stars[j]);
j++;
}
System.out.println("");
}
public void print() {
NightSky nightSky = new NightSky(this.density, this.width, this.height);
this.starsInLastPrint = 0;
int i = 0;
while (i < this.height) {
nightSky.printLine();
i++;
}
}
public int starsInLastPrint() {
return this.starsInLastPrint;
}
}
You are on the right track. Though, you don't need to instantiate another NightSky object inside the print method. You can just do the following,
public void print() {
this.starsInLastPrint = 0;
int i=0;
while (i < this.height) {
printLine();
i++;
}
}
So, everytime you call print, it will update the stars count for that print method call. Here is the whole code,
import java.util.Random;
public class NightSky {
private double density;
private int width;
private int height;
private int starsInLastPrint;
public static void main(String[] args){
NightSky sky = new NightSky(5,5);
sky.print();
System.out.println(sky.starsInLastPrint());
sky.print();
System.out.println(sky.starsInLastPrint());
}
public NightSky(double density) {
width = 20;
height = 10;
this.density = density;
}
public NightSky(int width, int height) {
density = 0.1;
this.width = width;
this.height = height;
}
public NightSky(double density, int width, int height) {
this.density = density;
this.width = width;
this.height = height;
}
public void printLine() {
Random starPlacement = new Random();
String[] stars = new String[(this.width)];
for (int i = 0; i < this.width; i++) {
double random = starPlacement.nextDouble();
if (random <= this.density) {
stars[i] = "*";
this.starsInLastPrint++;
} else {
stars[i] = " ";
}
}
int j = 0;
while (j < stars.length) {
System.out.print(stars[j]);
j++;
}
System.out.println("");
}
public void print() {
this.starsInLastPrint = 0;
int i=0;
while (i < this.height) {
printLine();
i++;
}
}
public int starsInLastPrint() {
return this.starsInLastPrint;
}
}
Sample run of the above code:
* *
*
*
4
0

Gabor Image Processing in Java without MathLab

I'm looking for some help in applying 2D Gabor Wavelets Formula to an image in java.
This is the formula that I'm using.
Gabor Formula
I need my output to look like this
I've read the image in and its currently stored in a 2D array. My code is as follows:` public void RunGabor() throws IOException
{
double[][]pixels=getImage();
int H= pixels.length;
int W =pixels[0].length;
size=H*W;
gaussian=size/2;
System.out.println(gaussian);
GaborGrid = new int[H][W];
GaborNorm = new int[H][W];
double X=0,Y=0, gx=-gaussian,gy=-gaussian, count=0, total=0;
int ax=0, dy=0;
for(int x=0; x<pixels.length; x++)
{
for(int k=0;k< pixels[0].length; k++)
{
X=gx*Math.cos(theta)+gy*Math.sin(theta);
Y=-gx*Math.sin(theta)+gy*Math.cos(theta);
pixels[dy][ax]=((Math.exp(-(Math.pow(X, 2)+(Math.pow(Y, 2)*
Math.pow(upsi,2)))/(2*Math.pow(sigma, 2))))*
(Math.cos((kappa*X+varphi))));
System.out.println("Pixels" +pixels[dy][ax]);
total+=pixels[dy][ax];
count++;
System.out.println("Count" +count);
gx+=1;
ax++;
}
System.out.println("second loop");
ax=0;
dy++;
gy+=1;
gx=-gaussian;
}
mean=total/count;
System.out.println("Mean" +mean);
NormaliseImage(pixels);
}`
From there it calls a method normaliseImage
public void NormaliseImage(double[][] pixels)
{
double minII = pixels[0][0];
double maxII = pixels[0][0];
for(int y=0; y<pixels.length; y++){
for(int x= 0; x<pixels[0].length; x++){
if(pixels[y][x] <= minII){
minII =pixels[y][x];
}
if(pixels[y][x]>= maxII){
maxII=pixels[y][x];
}
}
My create image class looks like this
public CreateImage(int[][] data, String IMGname)
{
name = IMGname;
width = data[0].length;
height = data.length;
System.out.println("NEW IMAGE 1");
pixels = new int[height*width];
int count=0;
for(int i=0; i<data.length; i++)
{
for(int j=0; j<data[0].length; j++)
{
pixels[count] = (int)Math.abs(data[i][j]);
pixels[count] = convert2pixel(pixels[count]);
count++;
}
}
Create(width, height, pixels, name);
}
public int convert2pixel(int pixel)
{
return ((0xff<<24)|(pixel<<16)|(pixel<<8)|pixel);
}
public int convert2grey(double pixel)
{
int red=((int)pixel>>16) & 0xff;
int green = ((int)pixel>>8) & 0xff;
int blue = (int)pixel & 0xff;
return (int)(0.3*red+0.6*green+0.1*blue);
}
public void Create(int Width, int Height, int pixels[], String n)//throws Exception
{
//System.out.println("Inside Create Image");
MemoryImageSource MemImg = new MemoryImageSource(Width,Height,pixels,0,Width);
Image img2= Toolkit.getDefaultToolkit().createImage(MemImg);
BufferedImage bfi = new BufferedImage(Height,Width, BufferedImage.TYPE_INT_BGR);
Graphics2D g2D = bfi.createGraphics();
g2D.drawImage(img2, 0, 0, Width, Height, null);
try
{
ImageIO.write(bfi, "png", new File(n+".png"));
}
catch(Exception e){}
}
}
My output is just a grey screen, any help would be appreciated.
Update: Gabor Driver Class `
public class Gabor_Driver{
public static void main(String[]args)throws IOException
{
double lamda=75;
double theta=45;
double varphi=90;
double upsi=10;
double bandW=10;
//int size=500;
Gabor gabor = new Gabor(lamda, theta, varphi, upsi, bandW );
}
}
`
Gabor class :
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
public class Gabor
{
CreateImage ci;
private double lamda=0;
private double theta=0;
private double varphi=0;
private double upsi=0;
private double bandW=0;
private double B=0;
private double sigma=0;
private double kappa=0;
private int[][] GaborGrid;
private int[][] GaborNorm;
int size=0;
double toRadians=180/Math.PI, min=500, max=-500, mean=0;;
int gaussian=0;
double rotation;
double GLFmean=0;
//Standard Gabor no quantization
public Gabor(double l, double t, double v, double u, double b) throws IOException
{
lamda=l;
theta=t/toRadians;
varphi=v/toRadians;
upsi=u;
bandW=b;
kappa=(2*Math.PI)/lamda;
Calculate_Sigma();
RunGabor();
}
public void RunGabor() throws IOException
{
double[][]pixels=getImage();
int H= pixels.length;
int W =pixels[0].length;
size=H*W;
gaussian=size/2;
System.out.println(gaussian);
GaborGrid = new int[H][W];
GaborNorm = new int[H][W];
double X=0,Y=0, gx=-gaussian,gy=-gaussian, count=0, total=0;
int ax=0, dy=0;
for(int x=0; x<pixels.length; x++)
{
for(int k=0;k< pixels[0].length; k++)
{
X=gx*Math.cos(theta)+gy*Math.sin(theta);
Y=-gx*Math.sin(theta)+gy*Math.cos(theta);
pixels[dy][ax]=((Math.exp(-(Math.pow(X, 2)+(Math.pow(Y, 2)*
Math.pow(upsi,2)))/(2*Math.pow(sigma, 2))))*
(Math.cos((kappa*X+varphi))));
System.out.println("Pixels" +pixels[dy][ax]);
total+=pixels[dy][ax];
count++;
System.out.println("Count" +count);
gx+=1;
ax++;
}
System.out.println("second loop");
ax=0;
dy++;
gy+=1;
gx=-gaussian;
}
mean=total/count;
System.out.println("Mean" +mean);
NormaliseImage(pixels);
}
public double[][] getImage() throws IOException{
int[][]pixels =null;
double[][] doubles = null;
JFileChooser fc = new JFileChooser();
int returnValue = fc.showOpenDialog(null);
if (returnValue == JFileChooser.APPROVE_OPTION) {
File selectedFile = fc.getSelectedFile();
BufferedImage image = ImageIO.read(selectedFile);
System.out.println(selectedFile.getName());
int W =image.getWidth();
int H= image.getHeight();
int width = image.getWidth();
int height = image.getHeight();
pixels = new int[height][width];
for (int row = 0; row < height; row++) {
image.getRGB(0, row, width, 1, pixels[row], 0, width);
}
doubles = new double[pixels.length][pixels[0].length];
for(int i=0; i<pixels.length; i++) {
for(int j=0; j<pixels[0].length; j++)
doubles[i][j] = pixels[+i][+j];
}
}
return doubles;
}
public void NormaliseImage(double[][] pixels)
{
double minII = pixels[0][0];
double maxII = pixels[0][0];
for(int y=0; y<pixels.length; y++){
for(int x= 0; x<pixels[0].length; x++){
if(pixels[y][x] <= minII){
minII =pixels[y][x];
}
if(pixels[y][x]>= maxII){
maxII=pixels[y][x];
}
}
}
int count=0;
double total=0;
for(int y=0; y<pixels.length; y++){
for(int x= 0; x<pixels[0].length; x++){
total += pixels[y][x];
count++;
}
}
double average =(double)total/count;
for(int y=0; y<pixels.length; y++){
for(int x= 0; x<pixels[0].length; x++){
double normalise= ((((pixels[y][x]-min))/((max-min)))*255);
if(normalise<=average){
normalise =0;
}
GaborNorm[y][x] = (int) normalise;
}
}
ci = new CreateImage(GaborNorm, "Gabor");
}
private void Calculate_Sigma()
{
B=(1/Math.PI)*(0.588705011)*((Math.pow(2, bandW)+1)/(Math.pow(2, bandW)-1));
sigma=B*lamda;
}
}
Create image class:
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
public class CreateImage
{
int[] pixels;
int width=0, height=0;
String name;
public CreateImage(int[][] data, String IMGname)
{
name = IMGname;
width = data[0].length;
height = data.length;
System.out.println("NEW IMAGE 1");
pixels = new int[height*width];
int count=0;
for(int i=0; i<data.length; i++)
{
for(int j=0; j<data[0].length; j++)
{
pixels[count] = (int)Math.abs(data[i][j]);
pixels[count] = convert2pixel(pixels[count]);
count++;
}
}
Create(width, height, pixels, name);
}
public int convert2pixel(int pixel)
{
return ((0xff<<24)|(pixel<<16)|(pixel<<8)|pixel);
}
public int convert2grey(double pixel)
{
int red=((int)pixel>>16) & 0xff;
int green = ((int)pixel>>8) & 0xff;
int blue = (int)pixel & 0xff;
return (int)(0.3*red+0.6*green+0.1*blue);
}
public void Create(int Width, int Height, int pixels[], String n)//throws Exception
{
//System.out.println("Inside Create Image");
MemoryImageSource MemImg = new MemoryImageSource(Width,Height,pixels,0,Width);
Image img2= Toolkit.getDefaultToolkit().createImage(MemImg);
BufferedImage bfi = new BufferedImage(Height,Width, BufferedImage.TYPE_INT_BGR);
Graphics2D g2D = bfi.createGraphics();
g2D.drawImage(img2, 0, 0, Width, Height, null);
try
{
ImageIO.write(bfi, "png", new File(n+".png"));
}
catch(Exception e){}
}
}
Your calculations are mostly correct. You are calculating the function itself in RunGabor - I think gx, gy should be replaced with x, k. This
for(int x=0; x<pixels.length; x++)
{
for(int k=0;k< pixels[0].length; k++)
{
X=gx*Math.cos(theta)+gy*Math.sin(theta);
Y=-gx*Math.sin(theta)+gy*Math.cos(theta);
pixels[dy][ax]=((Math.exp(-(Math.pow(X, 2)+(Math.pow(Y, 2)*
Math.pow(upsi,2)))/(2*Math.pow(sigma, 2))))*
(Math.cos((kappa*X+varphi))));
should be replaced with
public Kernel getKernel() {
double sigma = calculateSigma(waveLength, bandwidth);
float[] data = new float[width*height];
for(int k = 0, x = -width/2; x <= width/2; x++) {
for(int y = -height/2; y <= height/2; y++) {
for(double orientation : orientations) {
double x1 = x*Math.cos(orientation) + y*Math.sin(orientation);
double y1 = -x*Math.sin(orientation) + y*Math.cos(orientation);
data[k] += (float)(gaborFunction(x1, y1, sigma, aspectRatio, waveLength, phaseOffset));
}
k++;
}
}
But you have to apply the function on the pixels that you are reading, the image. If you look at this other implementation https://github.com/clumsy/gabor-filter/blob/master/src/main/java/GaborFilter.java
you will find many parallels. See if you can fix it.
At least as a first step you should try to print the values of the gabor function either 3x3 or 5x5. If they look reasonable you can go ahead to apply it to the image.

Raytracing: Dark rings appear

I am getting strange rings of black on my spheres when I render with lighting. I just added lighting and I cannot figure out why the black rings are being created.
Here is my code for my tracer.
public class Tracer {
public Camera Cam;
public int Width, Height;
public BufferedImage Image;
public Color BackGroundColor;
public int StartX, StartY, EndX, EndY,RowCount,ColCount;
public ArrayList<GeometricObject> GeoObjects;
public ArrayList<LightObject> LightObjects;
public boolean Tracing;
public double AmbientLight;
public Tracer(Camera cam, int width, int height, BufferedImage image, Color backGroundColor, int startX, int startY, int endX, int endY, int rowCount, int colCount, ArrayList<GeometricObject> Geoobjects,ArrayList<LightObject> Lightobjects,double ambientLight) {
super();
Cam = cam;
Width = width;
Height = height;
Image = image;
BackGroundColor = backGroundColor;
StartX = startX;
StartY = startY;
EndX = endX;
EndY = endY;
RowCount = rowCount;
ColCount = colCount;
GeoObjects = Geoobjects;
LightObjects = Lightobjects;
if(ambientLight > 1){
AmbientLight = 1;
}else if(ambientLight < 0){
AmbientLight = 0;
}else{
AmbientLight = ambientLight;
}
}
public void TracePixelFast(int x, int y) {
Color color = new Color(BackGroundColor.r,BackGroundColor.g,BackGroundColor.b);
for(int o = 0;o < GeoObjects.size();o++){
GeometricObject GO = GeoObjects.get(o);
Ray r = new Ray(Cam.GetRayPos(Width, Height, x, y, 1, 1, RowCount, ColCount), Cam.GetRayDir(Width, Height, x, y, 1,1, RowCount, ColCount));
double hit = GO.hit(r);
if (hit != 0.0) {
color = Cal_Pixel(x,y);
Image.setRGB(x, y, color.toInt());
break;
}
}
}
public void TracePixelSmooth(int x, int y) {
Image.setRGB(x, y,Cal_Pixel(x,y).toInt());
}
public Color Cal_Pixel(int x,int y){
Color color = new Color(BackGroundColor);
Color colorh = new Color(BackGroundColor);
Color bgc = new Color(BackGroundColor);
int HIT = 0;
int MISS = 0;
for (int row = 0; row < RowCount; row++) {
for (int col = 0; col < ColCount; col++) {
double min = Double.MAX_VALUE;
for (int o = 0; o < GeoObjects.size(); o++) {
GeometricObject GO = GeoObjects.get(o);
Ray r = new Ray(Cam.GetRayPos(Width, Height, x, y, row, col, RowCount, ColCount),Cam.GetRayDir(Width, Height, x, y, row, col, RowCount, ColCount));
double hit = GO.hit(r);
if (hit != 0.0 && hit < min) {
min = hit;
colorh = ShadePixel(GO, r, hit);
HIT++;
} else {
double min2 = Double.MAX_VALUE;
for (int o2 = 0; o2 < GeoObjects.size(); o2++) {
if(o!=o2){
GeometricObject GO2 = GeoObjects.get(o2);
double hit2 = GO2.hit(r);
if (hit2 != 0.0 && hit2 < min2) {
min2 = hit2;
bgc = ShadePixel(GO2, r, hit2);
}
}
}
MISS++;
}
}
}
}
for(int h = 0;h < HIT;h++){
color.Add(colorh);
}
for(int m = 0;m < MISS;m++){
color.Add(bgc);
}
color.Divide(RowCount * ColCount);
return color;
}
public Color ShadePixel(GeometricObject GO,Ray ray,double t){
ArrayList<Color> PixelShade = new ArrayList<Color>();
Normal normal = GO.Cal_Normal(ray, t);
for(int l = 0;l < LightObjects.size();l++){
LightObject light = LightObjects.get(l);
Vector3D r_Dir = light.Pos.Sub(normal.Origin);
r_Dir.normalize();
Ray raytolight = new Ray(normal.Origin,r_Dir);
int WAS_HIT = 0;
for(int o = 0;o < GeoObjects.size();o++){
GeometricObject NGO = GeoObjects.get(o);
double hit = NGO.hit(raytolight);
if (hit != 0.0) {
WAS_HIT = 1;
}
}
if(WAS_HIT == 0){
double Dot = normal.Direction.Dot(r_Dir);
if(Dot < 0){
Dot = 0;
}
double Diffuse = 1 - AmbientLight;
Color color = new Color(GO.Color);
double Shade = AmbientLight + Diffuse*Dot;
color.Mul(Shade);
PixelShade.add(color);
}else{
Color color = new Color(GO.Color);
double Shade = AmbientLight;
color.Mul(Shade);
PixelShade.add(color);
}
}
Color Final = new Color();
for(int s = 0;s < PixelShade.size();s++){
Final.Add(PixelShade.get(s));
}
Final.Divide(PixelShade.size());
return Final;
}
public void TraceArea(boolean SmoothTracing) {
Tracing = true;
if(SmoothTracing){
for (int x = StartX; x < EndX; x++) {
for (int y = StartY; y < EndY; y++) {
TracePixelSmooth(x,y);
}
}
}else{
for (int x = StartX; x < EndX; x++) {
for (int y = StartY; y < EndY; y++) {
TracePixelFast(x,y);
}
}
}
}
}
And here is the code for the sphere.
public class Sphere extends GeometricObject{
public Vector3D Center;
public double Radius;
public Sphere(Vector3D Center,double Radius,Color Color){
this.Center = Center;
this.Radius = Radius;
this.Color = Color;
}
public double hit(Ray ray) {
double a = ray.Direction.Dot(ray.Direction);
double b = 2 * ray.Origin.Sub(Center).Dot(ray.Direction);
double c = ray.Origin.Sub(Center).Dot(ray.Origin.Sub(Center))-Radius*Radius;
double discreminant = b*b-4*a*c;
if(discreminant < 0.0f){
return 0.0;
}else{
double t = (-b - Math.sqrt(discreminant))/(2*a);
if(t > 10E-9){
return t;
}else{
return 0.0;
}
}
}
public Normal Cal_Normal(Ray ray,double t) {
Vector3D NPos = new Vector3D(ray.Origin.x + ray.Direction.x*t,ray.Origin.y + ray.Direction.y*t,ray.Origin.z + ray.Direction.z*t);
Vector3D NDir = NPos.Sub(Center).Div(Radius);
return new Normal(NPos,NDir);
}
}
I am sure the problem is in shadepixel() but I could be wrong.
I just found out that the more objects that I add the more rings there are:
1 object no rings.
2 objects 1 ring.
3 objects 2 rings.
If you need me to post more of my code.Just ask and I will.
When I get back from school I will post my color class and fix the color problem. I still do not understand why the more objects (spheres) I add, the more rings there are. Can anyone explain to me why this is happening?
Here is my Color code.
public class Color {
public float r,g,b;
public Color(){
r = 0.0f;
g = 0.0f;
b = 0.0f;
}
public Color(float fr,float fg,float fb){
r = fr;
g = fg;
b = fb;
}
public Color(Color color){
r = color.r;
g = color.g;
b = color.b;
}
public void Add(Color color){
r += color.r;
g += color.g;
b += color.b;
}
public void Divide(int scalar){
r /= scalar;
g /= scalar;
b /= scalar;
}
public void Mul(double mul){
r *= mul;
g *= mul;
b *= mul;
}
public int toInt(){
return (int) (r*255)<<16 | (int) (g*255)<<8 | (int) (b*255);
}
There are multiple issues with this code, but the direct reason for the rings is that color component values are overflowing 0-255 range. This in turn is caused by incorrect calculations in what I take to be an attempt at antialiasing in Cal_Pixel(), as well as by no control whatsoever of numeric range in ShadePixel().
Think about how you can visually debug this scene.
First are the normals correct? Display them as the colour to see.
Taking the range for each component [-1..1] to the range [0..255]:
r = 255*(n.x + 1)/2;
g = 255*(n.y + 1)/2;
b = 255*(n.z + 1)/2;
Once you think they look correct move on to the next stage and build it up stage by stage.
e.g. you might look at if your dot product is as expected (again [-1..1] because the vectors are supposedly normalised):
r = 255*(dot + 1)/2;
g = 255*(dot + 1)/2;
b = 255*(dot + 1)/2;

JPanel size not changing

Hi guys i'm trying to create a draughts game in Java and am using JPanels to represent the squares, if I were to change the size of the panels how would I do so ? if I use a layout manager the squares are not big enough. At the moment i'm not using a layout manager to try and change the size, but the size doesnt seem to change - just stays at 1,1 pixel.
private void createSquares(){
for(int i = 0; i < 65; i++){
squares[i] = new JPanel();
squares[i].setLayout(null);
squares[i].setSize(20,20);
board.add(squares[i]);
}
}
You could always "borrow" an image or two online, and put that into your program. For example this code:
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class GetChessSquareImages {
public static final String PATH_TO_SQUARES = "http://www.colourbox.com/preview/" +
"4578561-622234-seamless-oak-square-chess-like-parquet-texture.jpg";
private static final int IMG_SIDE_COUNT = 4;
private static final double SCALE = 0.8;
private Map<SquareColor, List<Icon>> squareColorMap = new HashMap<SquareColor, List<Icon>>();
private Random random = new Random();
public void downloadImages() throws IOException {
URL lrgImgUrl = new URL(PATH_TO_SQUARES);
BufferedImage largeImg = ImageIO.read(lrgImgUrl);
int w = largeImg.getWidth() / IMG_SIDE_COUNT;
int h = largeImg.getHeight() / IMG_SIDE_COUNT;
for (int i = 0; i < IMG_SIDE_COUNT; i++) {
int x = (i * largeImg.getWidth()) / IMG_SIDE_COUNT;
for (int j = 0; j < IMG_SIDE_COUNT; j++) {
if (j != 1 && j != 2) {
int y = (j * largeImg.getHeight()) / IMG_SIDE_COUNT;
extractSubImg(largeImg, i, j, x, y, w, h);
}
}
}
}
private void extractSubImg(BufferedImage largeImg,
int i, int j, int x, int y, int w, int h) {
Image subImg = largeImg.getSubimage(x, y, w, h);
int width = (int) (w * SCALE);
int height = (int) (h * SCALE);
subImg = subImg.getScaledInstance(width, height, Image.SCALE_SMOOTH);
List<Icon> iconList = null;
if (i % 2 == j % 2) {
iconList = squareColorMap.get(SquareColor.LIGHT);
if (iconList == null) {
iconList = new ArrayList<Icon>();
squareColorMap.put(SquareColor.LIGHT, iconList);
}
} else {
iconList = squareColorMap.get(SquareColor.DARK);
if (iconList == null) {
iconList = new ArrayList<Icon>();
squareColorMap.put(SquareColor.DARK, iconList);
}
}
iconList.add(new ImageIcon(subImg));
}
public Icon getRandomIcon(SquareColor sqrColor) {
List<Icon> iconList = squareColorMap.get(sqrColor);
if (iconList == null) {
return null;
} else {
return iconList.get(random.nextInt(iconList.size()));
}
}
public static void main(String[] args) {
GetChessSquareImages getImages = new GetChessSquareImages();
try {
getImages.downloadImages();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
int side = 8;;
JPanel panel = new JPanel(new GridLayout(side , side));
for (int i = 0; i < side; i++) {
for (int j = 0; j < side; j++) {
SquareColor sqrColor = (i % 2 == j % 2) ? SquareColor.LIGHT : SquareColor.DARK;
Icon icon = getImages.getRandomIcon(sqrColor);
panel.add(new JLabel(icon));
}
}
JOptionPane.showMessageDialog(null, panel);
}
}
enum SquareColor {
DARK, LIGHT
}
returns this JPanel:
Then your square size will be based on the sizes of your ImageIcons. For example, I have scaled my squares back with a scale factor of 0.8 (the SCALE constant above) to make the grid a more reasonable size.

Convert Image to Grayscale with array matrix RGB java

I'm creating an Image filter program and I want to convert a coloured picture to a grayscale picture with the help of an array matrix.
This is what I have currently:
import java.awt.Color;
import se.lth.cs.ptdc.images.ImageFilter;
public class GrayScaleFilter extends ImageFilter {
public GrayScaleFilter(String name){
super(name);
}
public Color[][] apply(Color[][] inPixels, double paramValue){
int height = inPixels.length;
int width = inPixels[0].length;
Color[][] outPixels = new Color[height][width];
for (int i = 0; i < 256; i++) {
grayLevels[i] = new Color(i, i, i);
}
for(int i = 0; i < height; i++){
for(int j = 0; j < width; j++){
Color pixel = inPixels[i][j];
outPixels[i][j] = grayLevels[index];
}
}
return outPixels;
}
}
It looks like I'm supposed to use this formula: ((R+G+B)/3)
I want to create an array matrix like this:
Color[] grayLevels = new Color[256];
// creates the color (0,0,0) and puts it in grayLevels[0],
// (1,1,1) in grayLevels[1], ..., (255,255,255) in grayLevels[255]
This is the class I'm refering too when I want to use grascale:
public abstract Color[][] apply(Color[][] inPixels, double paramValue);
protected short[][] computeIntensity(Color[][] pixels) {
int height = pixels.length;
int width = pixels[0].length;
short[][] intensity = new short[height][width];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
Color c = pixels[i][j];
intensity[i][j] = (short) ((c.getRed() + c.getGreen() + c
.getBlue()) / 3);
}
}
return intensity;
}
Any feedback on how I can achieve this? Instead of using outPixels[i][j] = new Color(intensity, intensity, intensity);
Build the grayLevels array this way:
for (int i = 0; i < 256; i++) {
grayLevels[i] = new Color(i, i, i);
}
Then, when you need a certain color, just retrieve it as grayLevels[index].

Categories

Resources