I have completed some of the code for a color wheel, but I'm confused on how to complete it? I've also commented the code to help understand. So far, it prints red, orange and yellow gradients. How do I complete this?
import java.awt.*;
public class ColorDrawing2 {
public static final int CENTER = 256;
public static final int RADIUS = 120;
public static final int SHAPES = 32;
public static final int SIZE = 40;
public static void main(String[] args) {
DrawingPanel panel = new DrawingPanel(512,512); // create a drawing panel
panel.setBackground(new Color(0,0,0)); // set background color (orange)
Graphics g = panel.getGraphics(); // get graphics toolkit
for (int i = 0; i <= SHAPES; i++) {
// System.out.println("i = " + i);
double angle = (i)*(360/SHAPES)*(Math.PI/180); // angle
// System.out.println("Angle = " + angle);
double x = CENTER - (SIZE/2) + RADIUS*Math.cos(angle); // x-cooordinate
double y = CENTER - (SIZE/2) + RADIUS*Math.sin(angle); // y-coordinate
int red = (int) (199 + 56/SHAPES*i); // 199 < red < 255
// System.out.println("Red = " + red);
int grn = (int) (7.97*i); // 0 < grn < 255
// System.out.println("Green = " + grn);
int blu = 0;
g.setColor(new Color((int) red, grn, blu));
g.fillOval((int)x, (int)y, SIZE, SIZE);
panel.sleep(200); // pause 200 msec
}
}
}
Yes, seems like 6 for loops should be enough. Maybe the colors should go up to 255?
for the 6 for loops:
for (int i = 0; i <= SHAPES; i++) {
// System.out.println("i = " + i);
double angle = ((i)*(60/SHAPES) +65)*(Math.PI/180); // angle
// System.out.println("Angle = " + angle);
double x = CENTER - (SIZE/2) + RADIUS*Math.cos(angle); // x-cooordinate
double y = CENTER - (SIZE/2) + RADIUS*Math.sin(angle); // y-coordinate
int red = (int) (255); // 199 < red < 255
// System.out.println("Red = " + red);
int grn = (int) (7.97*i); // 0 < grn < 255
// System.out.println("Green = " + grn);
int blu = 0;
g.setColor(new Color((int) red, grn, blu));
g.fillOval((int)x, (int)y, SIZE, SIZE);
panel.sleep(0); // pause 200 msec
}
for (int i = 0; i <= SHAPES; i++) {
// System.out.println("i = " + i);
double angle = ((i)*(60/SHAPES) + 130)*(Math.PI/180); // angle
// System.out.println("Angle = " + angle);
double x = CENTER - (SIZE/2) + RADIUS*Math.cos(angle); // x-cooordinate
double y = CENTER - (SIZE/2) + RADIUS*Math.sin(angle); // y-coordinate
int red = (int) (255 - (255/SHAPES*i)); // 199 < red < 255
// System.out.println("Red = " + red);
int grn = (int) (255); // 0 < grn < 255
// System.out.println("Green = " + grn);
int blu = 0;
g.setColor(new Color((int) red, grn, blu));
g.fillOval((int)x, (int)y, SIZE, SIZE);
panel.sleep(0); // pause 200 msec
}
for (int i = 0; i <= SHAPES; i++) {
// System.out.println("i = " + i);
double angle = ((i)*(60/SHAPES) + 185)*(Math.PI/180); // angle
// System.out.println("Angle = " + angle);
double x = CENTER - (SIZE/2) + RADIUS*Math.cos(angle); // x-cooordinate
double y = CENTER - (SIZE/2) + RADIUS*Math.sin(angle); // y-coordinate
int red = (int) (0); // 199 < red < 255
// System.out.println("Red = " + red);
int grn = (int) (255); // 0 < grn < 255
// System.out.println("Green = " + grn);
int blu = (int) (7.97*i);
g.setColor(new Color((int) red, grn, blu));
g.fillOval((int)x, (int)y, SIZE, SIZE);
panel.sleep(0); // pause 200 msec
}
for (int i = 0; i <= SHAPES; i++) {
// System.out.println("i = " + i);
double angle = ((i)*(60/SHAPES) + 250)*(Math.PI/180); // angle
// System.out.println("Angle = " + angle);
double x = CENTER - (SIZE/2) + RADIUS*Math.cos(angle); // x-cooordinate
double y = CENTER - (SIZE/2) + RADIUS*Math.sin(angle); // y-coordinate
int red = (int) (0); // 199 < red < 255
// System.out.println("Red = " + red);
int grn = (int) (255 - (255/SHAPES*i)); // 0 < grn < 255
// System.out.println("Green = " + grn);
int blu = (int) (255);
g.setColor(new Color((int) red, grn, blu));
g.fillOval((int)x, (int)y, SIZE, SIZE);
panel.sleep(0); // pause 200 msec
}
for (int i = 0; i <= SHAPES; i++) {
// System.out.println("i = " + i);
double angle = ((i)*(60/SHAPES) + 315)*(Math.PI/180); // angle
// System.out.println("Angle = " + angle);
double x = CENTER - (SIZE/2) + RADIUS*Math.cos(angle); // x-cooordinate
double y = CENTER - (SIZE/2) + RADIUS*Math.sin(angle); // y-coordinate
int red = (int) (7.97*i); // 199 < red < 255
// System.out.println("Red = " + red);
int grn = (int) (0); // 0 < grn < 255
// System.out.println("Green = " + grn);
int blu = (int) (255);
g.setColor(new Color((int) red, grn, blu));
g.fillOval((int)x, (int)y, SIZE, SIZE);
panel.sleep(0); // pause 200 msec
}
for (int i = 0; i <= SHAPES; i++) {
// System.out.println("i = " + i);
double angle = ((i)*(60/SHAPES) +370)*(Math.PI/180); // angle
// System.out.println("Angle = " + angle);
double x = CENTER - (SIZE/2) + RADIUS*Math.cos(angle); // x-cooordinate
double y = CENTER - (SIZE/2) + RADIUS*Math.sin(angle); // y-coordinate
int red = (int) (7.97*i); // 199 < red < 255
// System.out.println("Red = " + red);
int grn = (int) (0); // 0 < grn < 255
// System.out.println("Green = " + grn);
int blu = (int) (0);
g.setColor(new Color((int) red, grn, blu));
g.fillOval((int)x, (int)y, SIZE, SIZE);
panel.sleep(0); // pause 200 msec
}
Related
I'm trying to implement flood fill algorithm using to fill the closed shape with specific color.
I think my code is worked out, but i don't know why are"StackOverflowError" rising up !!
i looked for the solution more and more but without finding the perfect answer.
public void paintComponent(Graphics g){
indecies.clear();
float x1 = 20;
float y1 = 20;
float x2 = 350;
float y2 = 20;
/* put the points of first line in ArraList */
for(int i = (int) x1; i < x2 ; i++){
index = (int) (i + y1 * img.getWidth());
list.add(index);
}
/***************************************************/
x1 = 350;
y1 = 20;
x2 = 100;
y2 = 100;
/* put the points of second line in ArraList */
for(int i = (int) y1; i <= y2 ; i++){
index = (int) (x1 * img.getWidth());
list.add(index);
}
/***************************************************/
x1 = 100;
y1 = 100;
x2 = 20;
y2 = 100;
/* put the points of the third line in ArraList */
for(int i = (int) x2; i < x1 ; i++){
index = (int) (i + y1 * img.getWidth());
list.add(index);
}
/*****************************************************/
x1 = 20;
y1 = 100;
x2 = 20;
y2 = 20;
/* put the points of the forth line in ArraList */
for(int i = (int) y2; i < y1 ; i++){
index = (int) (x1 * img.getWidth());
list.add(index);
}
/**************************************************/
/* Get each pixel from ArrayList of indecies then print into data raster of image */
for (Integer integer : indecies) {
pixels[integer] = Color.yellow.getRGB();
}
/* Flood fill recursive algorithm */
/* border color is yellow */
/* green is the new colow must be filled inside the shape */
fill(50, 50, Color.yellow.getRGB(), Color.green.getRGB());
g.drawImage(img, 0, 0, this);
}
Here is the fill method !!
public void fill(int x, int y, int borderColor, int newColor){
if(x >= 0 && x < width && y >= 0 && y < height){
int index = x + y * width;
if(pixels[index] != borderColor && pixels[index] != newColor){
pixels[index] = newColor;
fill(x, y - 1, borderColor, newColor);
fill(x, y + 1, borderColor, newColor);
fill(x + 1, y, borderColor, newColor);
fill(x - 1, y, borderColor, newColor);
}
}
}
Exception Details ..
java.lang.StackOverflowErrorjava.lang.StackOverflowErrorjava.lang.StackOverflowErrorjava.lang.StackOverflowErrorjava.lang.StackOverflowErrorjava.lang.StackOverflowError
at java.nio.Buffer.limit(Buffer.java:274)
at java.nio.Buffer.<init>(Buffer.java:201)
at java.nio.CharBuffer.<init>(CharBuffer.java:281)
at java.nio.HeapCharBuffer.<init>(HeapCharBuffer.java:70)
at java.nio.CharBuffer.wrap(CharBuffer.java:373)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:265)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
at java.io.PrintStream.write(PrintStream.java:526)
at java.io.PrintStream.print(PrintStream.java:669)
at java.io.PrintStream.println(PrintStream.java:823)
at java.lang.Throwable$WrappedPrintStream.println(Throwable.java:748)
at java.lang.Throwable.printStackTrace(Throwable.java:655)
at java.lang.Throwable.printStackTrace(Throwable.java:643)
at java.lang.Throwable.printStackTrace(Throwable.java:634)
at FillColorAlgorithm.fill(FillColorAlgorithm.java:170)
at FillColorAlgorithm.fill(FillColorAlgorithm.java:162)
......... etc
public void floodFill(int x, int y, int borderColor, int fillColor, int imgWidth, int imgHeight){
Queue<java.awt.Point> nodesList = new LinkedList<>();
if(borderColor == fillColor) return;
if(x >= 0 && x < imgWidth && y >= 0 && y < imgHeight){
int index = x + y * imgWidth;
if(pixels[index] == fillColor) return;
nodesList.add(new java.awt.Point(x, y));
}
while(!nodesList.isEmpty()) {
java.awt.Point currentNode = nodesList.element();
int index = currentNode.x + currentNode.y * imgWidth;
if(pixels[index] != fillColor){
java.awt.Point westNode = currentNode;
java.awt.Point eastNode = currentNode;
westNode = MoveWest(westNode, borderColor);
eastNode = MoveEast(eastNode, borderColor);
for (int j = westNode.x + 1; j < eastNode.x; j++) {
index = j + currentNode.y * imgWidth;
pixels[index] = fillColor;
java.awt.Point northNode = new java.awt.Point(j, currentNode.y - 1);
java.awt.Point southNode = new java.awt.Point(j, currentNode.y + 1);
index = northNode.x + northNode.y * imgWidth;
if(northNode.y >= 0 && pixels[index] != fillColor && pixels[index] != borderColor) nodesList.add(northNode);
index = southNode.x + southNode.y * imgWidth;
if(southNode.y < imgHeight && pixels[index] != fillColor && pixels[index] != borderColor) nodesList.add(southNode);
}
}
nodesList.remove();
}
}
java.awt.Point MoveWest(java.awt.Point w, int borderColor){
int index;
do{
--w.x;
index = w.x + w.y * width;
}
while(w.x >= 0 && pixels[index] != borderColor);
return new java.awt.Point(w.x, w.y);
}
java.awt.Point MoveEast(java.awt.Point e, int borderColor){
int index;
do{
++e.x;
index = e.x + e.y * width;
}
while( e.x < width && pixels[index] != borderColor);
return new java.awt.Point(e.x, e.y);
}
The image rotates with code below, but wrong, some black dots appears on original image. I believe it's something with rotation code. Any solution? Thanks. The image dimensions is 32x32 pixels loaded on center of screen (320x240).
public class RendPanel extends JPanel {
private static final long serialVersionUID = 1L;
int widthe = 320;
int heighte = 240;
double angle = Math.toRadians(220);
double sin = Math.sin(angle);
double cos = Math.cos(angle);
double x0 = 0.5 * (widthe - 1); // point to rotate about
double y0 = 0.5 * (heighte - 1); // center of image
public static BufferedImage fbuffer;
public RendPanel(int width, int height) {
fbuffer = new BufferedImage(320, 240, BufferedImage.TYPE_INT_RGB);
BufferedImage in = null;
try { in = ImageIO.read(new File("square.png")); } //32x32 square .png
catch (IOException e) { e.printStackTrace(); }
for (int i = 0; i < in.getWidth(); i++) {
for (int j = 0; j < in.getHeight(); j++) {
fbuffer.setRGB(i + (320 / 2) - 16, j + (240 / 2) - 16, in.getRGB(i, j));
}
}
BufferedImage neww = new BufferedImage(320, 240, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < widthe; x++) {
for (int y = 0; y < heighte; y++) {
if(x >= x0 - 32 && x <= x0 + 32 && y >= y0 - 32 && y <= y0 + 32){
double a = x - x0;
double b = y - y0;
int xx = (int) (+a * cos - b * sin + x0);
int yy = (int) (+a * sin + b * cos + y0);
// plot pixel (x, y) the same color as (xx, yy) if it's in bounds
if (xx >= 0 && xx < width && yy >= 0 && yy < height) {
neww.setRGB(xx, yy, fbuffer.getRGB(x, y));
}
}
}
}
fbuffer = neww;
repaint();
setPreferredSize(new Dimension(width, height));
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(fbuffer, 0, 0, null);
}
}
A beginner's mistake (sorry).
Taking every source pixel in turn, transforming the coordinates to the destination and copying the pixel value is not the right way.because the regular input grid will not map to a regular grid, and there will be voids (and overlaps).
The correct way is to scan the destination image (so that every destination pixel is reached) and counter-transform the coordinates to fetch the pixel value from the source.
As a refinement, you can use the four neighboring pixel from where you land in the source and perform bilinear interpolation, to reduce aliasing.
Man, it's strange, because in this code it works properly!
Heres a working code:
public class RendPanel extends JPanel {
private static final long serialVersionUID = 1L;
int widthe = 320;
int heighte = 240;
int ang = 0;
double x0 = 0.5 * (widthe - 1); // point to rotate about
double y0 = 0.5 * (heighte - 1); // center of image
public static BufferedImage fbuffer;
public RendPanel(int width, int height) {
fbuffer = new BufferedImage(320, 240, BufferedImage.TYPE_INT_RGB);
BufferedImage in = null;
try { in = ImageIO.read(new File("square.png")); } //32x32 square .png
catch (IOException e) { e.printStackTrace(); }
for (int i = 0; i < in.getWidth(); i++) {
for (int j = 0; j < in.getHeight(); j++) {
fbuffer.setRGB(i + (320 / 2) - 16, j + (240 / 2) - 16, in.getRGB(i, j));
}
}
setPreferredSize(new Dimension(width, height));
}
BufferedImage neww;
public void r(){
neww = new BufferedImage(320, 240, BufferedImage.TYPE_INT_RGB);
double angle = Math.toRadians(ang);
double sin = Math.sin(angle);
double cos = Math.cos(angle);
for (int x = 0; x < widthe; x++) {
for (int y = 0; y < heighte; y++) {
if(x >= x0 - 32 && x <= x0 + 32 && y >= y0 - 32 && y <= y0 + 32){
double a = x - x0;
double b = y - y0;
int xx = (int) (+a * cos - b * sin + x0);
int yy = (int) (+a * sin + b * cos + y0);
// plot pixel (x, y) the same color as (xx, yy) if it's in bounds
if (xx >= 0 && xx < widthe && yy >= 0 && yy < heighte) {
neww.setRGB(x, y, fbuffer.getRGB(xx, yy));
}
}
}
}
ang++;
repaint();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(neww, 0, 0, null);
}
}
Thanks for:
https://introcs.cs.princeton.edu/java/31datatype/Rotation.java.html
EDIT:
You have to invert the vars on bf2.setRGB(x, y, fbuffer.getRGB(xx, yy)); to the rotated coordinate.
I was using this code placed here to generate bar-charts for my datasets. However, the colours were all the same (red in the code), so I decided to generate a colour ramp for this. I wrote the following code:
Color[] getColorRamp(int numColours)
{
Color[] colours = new Color[numColours];
int red_1 = 255;
int green_1 = 0;
int blue_1 = 0;
int red_2 = 0;
int green_2 = 0;
int blue_2 = 255;
int count = 0;
for (float t=0.0f;t<1.0f;t+=1.0/(float)numColours) {
colours[count] = new Color((int)(t*red_2 + (1-t)*red_1),
(int)(t*green_2 + (1-t)*green_1),
(int)(t*blue_2 + (1-t)*blue_1),34);
//System.out.print((int)(t*red_2 + (1-t)*red_1) +",");
//System.out.print((int)(t*green_2 + (1-t)*green_1) +",");
//System.out.println((int)(t*blue_2 + (1-t)*blue_1));
}
return colours;
}
It is here, where the problem starts. Only the first colour (pretty light blue) get rendered properly. Other colours are rendered as black! You can see that I have put System.out.println to verify the colours generated (commented in the code posted here). I saw that colours were generated as perfect RGB combinations.
The modified barchart function is posted here:
void drawBarChart(Graphics g, double[] values, String[] names, String title)
{
if (values == null || values.length == 0)
return;
double minValue = 0;
double maxValue = 0;
for (int i = 0; i < values.length; i++) {
if (minValue > values[i])
minValue = values[i];
if (maxValue < values[i])
maxValue = values[i];
}
//Graphics2D g = (Graphics2D)gg;
Dimension d = getSize();
int clientWidth = d.width;
int clientHeight = d.height;
int barWidth = clientWidth / values.length;
Font titleFont = new Font("SansSerif", Font.BOLD, 20);
FontMetrics titleFontMetrics = g.getFontMetrics(titleFont);
Font labelFont = new Font("SansSerif", Font.PLAIN, 10);
FontMetrics labelFontMetrics = g.getFontMetrics(labelFont);
int titleWidth = titleFontMetrics.stringWidth(title);
int y = titleFontMetrics.getAscent();
int x = (clientWidth - titleWidth) / 2;
g.setFont(titleFont);
g.drawString(title, x, y);
int top = titleFontMetrics.getHeight();
int bottom = labelFontMetrics.getHeight();
if (maxValue == minValue)
return;
double scale = (clientHeight - top - bottom) / (maxValue - minValue);
y = clientHeight - labelFontMetrics.getDescent();
g.setFont(labelFont);
Color[] colours = getColorRamp(values.length);
for (int i = 0; i < values.length; i++) {
int valueX = i * barWidth + 1;
int valueY = top;
int height = (int) (values[i] * scale);
if (values[i] >= 0)
valueY += (int) ((maxValue - values[i]) * scale);
else {
valueY += (int) (maxValue * scale);
height = -height;
}
g.setColor(colours[i]);
g.fillRect(valueX, valueY, barWidth - 2, height);
g.setColor(Color.black);
g.drawRect(valueX, valueY, barWidth - 2, height);
int labelWidth = labelFontMetrics.stringWidth(names[i]);
x = i * barWidth + (barWidth - labelWidth) / 2;
g.drawString(names[i], x, y);
}
//paintComponent(g);
}
I wish to know, what mistake I am making!
You're probably going to hit yourself on the head now. The reason it fails is that you forget to increase the variable count after setting the first colour, so you're constantly overwriting the first element of the Color array, and leaving all the other values in the array as their initial default (null).
Fixed code:
for (float t=0.0f;t<1.0f;t+=1.0/(float)numColours) {
colours[count++] = new Color((int)(t*red_2 + (1-t)*red_1),
(int)(t*green_2 + (1-t)*green_1),
(int)(t*blue_2 + (1-t)*blue_1),34);
}
(Notice the colours[count++])
I found some code that draws the histogram but I am not sure how to make it show the histogram of _tempBitmaps[0] once the user clicks on a ShowRGB Histogram Button
I want the graphs to be displayed on top of ImageView once the user clicks the button display_RGB and when the user clicks the button again the graphs disappear.
I have also attached a mockup of the layout and the graphs that I wish to achieve.
Mockup:
Below is the sample code I found for histogram and it works but currently some of the variables arent initialised and thats what I need help with :
class DrawOnTop extends View {
Bitmap mBitmap;
Paint mPaintBlack;
Paint mPaintYellow;
Paint mPaintRed;
Paint mPaintGreen;
Paint mPaintBlue;
byte[] mYUVData;
int[] mRGBData;
int mImageWidth, mImageHeight;
int[] mRedHistogram;
int[] mGreenHistogram;
int[] mBlueHistogram;
double[] mBinSquared;
public DrawOnTop(Context context) {
super(context);
mPaintBlack = new Paint();
mPaintBlack.setStyle(Paint.Style.FILL);
mPaintBlack.setColor(Color.BLACK);
mPaintBlack.setTextSize(25);
mPaintYellow = new Paint();
mPaintYellow.setStyle(Paint.Style.FILL);
mPaintYellow.setColor(Color.YELLOW);
mPaintYellow.setTextSize(25);
mPaintRed = new Paint();
mPaintRed.setStyle(Paint.Style.FILL);
mPaintRed.setColor(Color.RED);
mPaintRed.setTextSize(25);
mPaintGreen = new Paint();
mPaintGreen.setStyle(Paint.Style.FILL);
mPaintGreen.setColor(Color.GREEN);
mPaintGreen.setTextSize(25);
mPaintBlue = new Paint();
mPaintBlue.setStyle(Paint.Style.FILL);
mPaintBlue.setColor(Color.BLUE);
mPaintBlue.setTextSize(25);
mBitmap = null;
mYUVData = null;
mRGBData = null;
mRedHistogram = new int[256];
mGreenHistogram = new int[256];
mBlueHistogram = new int[256];
mBinSquared = new double[256];
for (int bin = 0; bin < 256; bin++)
{
mBinSquared[bin] = ((double)bin) * bin;
} // bin
}
#Override
protected void onDraw(Canvas canvas) {
if (mBitmap != null)
{
int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
int newImageWidth = canvasWidth;
int newImageHeight = canvasHeight;
int marginWidth = (canvasWidth - newImageWidth)/2;
// Convert from YUV to RGB
decodeYUV420SP(mRGBData, mYUVData, mImageWidth, mImageHeight);
// Draw bitmap
mBitmap.setPixels(mRGBData, 0, mImageWidth, 0, 0,
mImageWidth, mImageHeight);
Rect src = new Rect(0, 0, mImageWidth, mImageHeight);
Rect dst = new Rect(marginWidth, 0,
canvasWidth-marginWidth, canvasHeight);
canvas.drawBitmap(mBitmap, src, dst, mPaintBlack);
// Draw black borders
canvas.drawRect(0, 0, marginWidth, canvasHeight, mPaintBlack);
canvas.drawRect(canvasWidth - marginWidth, 0,
canvasWidth, canvasHeight, mPaintBlack);
// Calculate histogram
calculateIntensityHistogram(mRGBData, mRedHistogram,
mImageWidth, mImageHeight, 0);
calculateIntensityHistogram(mRGBData, mGreenHistogram,
mImageWidth, mImageHeight, 1);
calculateIntensityHistogram(mRGBData, mBlueHistogram,
mImageWidth, mImageHeight, 2);
// Calculate mean
double imageRedMean = 0, imageGreenMean = 0, imageBlueMean = 0;
double redHistogramSum = 0, greenHistogramSum = 0, blueHistogramSum = 0;
for (int bin = 0; bin < 256; bin++)
{
imageRedMean += mRedHistogram[bin] * bin;
redHistogramSum += mRedHistogram[bin];
imageGreenMean += mGreenHistogram[bin] * bin;
greenHistogramSum += mGreenHistogram[bin];
imageBlueMean += mBlueHistogram[bin] * bin;
blueHistogramSum += mBlueHistogram[bin];
} // bin
imageRedMean /= redHistogramSum;
imageGreenMean /= greenHistogramSum;
imageBlueMean /= blueHistogramSum;
// Calculate second moment
double imageRed2ndMoment = 0, imageGreen2ndMoment = 0, imageBlue2ndMoment = 0;
for (int bin = 0; bin < 256; bin++)
{
imageRed2ndMoment += mRedHistogram[bin] * mBinSquared[bin];
imageGreen2ndMoment += mGreenHistogram[bin] * mBinSquared[bin];
imageBlue2ndMoment += mBlueHistogram[bin] * mBinSquared[bin];
} // bin
imageRed2ndMoment /= redHistogramSum;
imageGreen2ndMoment /= greenHistogramSum;
imageBlue2ndMoment /= blueHistogramSum;
double imageRedStdDev = Math.sqrt( imageRed2ndMoment - imageRedMean*imageRedMean );
double imageGreenStdDev = Math.sqrt( imageGreen2ndMoment - imageGreenMean*imageGreenMean );
double imageBlueStdDev = Math.sqrt( imageBlue2ndMoment - imageBlueMean*imageBlueMean );
// Draw mean
String imageMeanStr = "Mean (R,G,B): " + String.format("%.4g", imageRedMean) + ", " + String.format("%.4g", imageGreenMean) + ", " + String.format("%.4g", imageBlueMean);
canvas.drawText(imageMeanStr, marginWidth+10-1, 30-1, mPaintBlack);
canvas.drawText(imageMeanStr, marginWidth+10+1, 30-1, mPaintBlack);
canvas.drawText(imageMeanStr, marginWidth+10+1, 30+1, mPaintBlack);
canvas.drawText(imageMeanStr, marginWidth+10-1, 30+1, mPaintBlack);
canvas.drawText(imageMeanStr, marginWidth+10, 30, mPaintYellow);
// Draw standard deviation
String imageStdDevStr = "Std Dev (R,G,B): " + String.format("%.4g", imageRedStdDev) + ", " + String.format("%.4g", imageGreenStdDev) + ", " + String.format("%.4g", imageBlueStdDev);
canvas.drawText(imageStdDevStr, marginWidth+10-1, 60-1, mPaintBlack);
canvas.drawText(imageStdDevStr, marginWidth+10+1, 60-1, mPaintBlack);
canvas.drawText(imageStdDevStr, marginWidth+10+1, 60+1, mPaintBlack);
canvas.drawText(imageStdDevStr, marginWidth+10-1, 60+1, mPaintBlack);
canvas.drawText(imageStdDevStr, marginWidth+10, 60, mPaintYellow);
// Draw red intensity histogram
float barMaxHeight = 3000;
float barWidth = ((float)newImageWidth) / 256;
float barMarginHeight = 2;
RectF barRect = new RectF();
barRect.bottom = canvasHeight - 200;
barRect.left = marginWidth;
barRect.right = barRect.left + barWidth;
for (int bin = 0; bin < 256; bin++)
{
float prob = (float)mRedHistogram[bin] / (float)redHistogramSum;
barRect.top = barRect.bottom -
Math.min(80,prob*barMaxHeight) - barMarginHeight;
canvas.drawRect(barRect, mPaintBlack);
barRect.top += barMarginHeight;
canvas.drawRect(barRect, mPaintRed);
barRect.left += barWidth;
barRect.right += barWidth;
} // bin
// Draw green intensity histogram
barRect.bottom = canvasHeight - 100;
barRect.left = marginWidth;
barRect.right = barRect.left + barWidth;
for (int bin = 0; bin < 256; bin++)
{
barRect.top = barRect.bottom - Math.min(80, ((float)mGreenHistogram[bin])/((float)greenHistogramSum) * barMaxHeight) - barMarginHeight;
canvas.drawRect(barRect, mPaintBlack);
barRect.top += barMarginHeight;
canvas.drawRect(barRect, mPaintGreen);
barRect.left += barWidth;
barRect.right += barWidth;
} // bin
// Draw blue intensity histogram
barRect.bottom = canvasHeight;
barRect.left = marginWidth;
barRect.right = barRect.left + barWidth;
for (int bin = 0; bin < 256; bin++)
{
barRect.top = barRect.bottom - Math.min(80, ((float)mBlueHistogram[bin])/((float)blueHistogramSum) * barMaxHeight) - barMarginHeight;
canvas.drawRect(barRect, mPaintBlack);
barRect.top += barMarginHeight;
canvas.drawRect(barRect, mPaintBlue);
barRect.left += barWidth;
barRect.right += barWidth;
} // bin
} // end if statement
super.onDraw(canvas);
} // end onDraw method
static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
final int frameSize = width * height;
for (int j = 0, yp = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0) y = 0;
if ((i & 1) == 0) {
v = (0xff & yuv420sp[uvp++]) - 128;
u = (0xff & yuv420sp[uvp++]) - 128;
}
int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192 - 833 * v - 400 * u);
int b = (y1192 + 2066 * u);
if (r < 0) r = 0; else if (r > 262143) r = 262143;
if (g < 0) g = 0; else if (g > 262143) g = 262143;
if (b < 0) b = 0; else if (b > 262143) b = 262143;
rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
}
}
}
static public void decodeYUV420SPGrayscale(int[] rgb, byte[] yuv420sp, int width, int height)
{
final int frameSize = width * height;
for (int pix = 0; pix < frameSize; pix++)
{
int pixVal = (0xff & ((int) yuv420sp[pix])) - 16;
if (pixVal < 0) pixVal = 0;
if (pixVal > 255) pixVal = 255;
rgb[pix] = 0xff000000 | (pixVal << 16) | (pixVal << 8) | pixVal;
} // pix
}
static public void calculateIntensityHistogram(int[] rgb, int[] histogram, int width, int height, int component)
{
for (int bin = 0; bin < 256; bin++)
{
histogram[bin] = 0;
} // bin
if (component == 0) // red
{
for (int pix = 0; pix < width*height; pix += 3)
{
int pixVal = (rgb[pix] >> 16) & 0xff;
histogram[ pixVal ]++;
} // pix
}
else if (component == 1) // green
{
for (int pix = 0; pix < width*height; pix += 3)
{
int pixVal = (rgb[pix] >> 8) & 0xff;
histogram[ pixVal ]++;
} // pix
}
else // blue
{
for (int pix = 0; pix < width*height; pix += 3)
{
int pixVal = rgb[pix] & 0xff;
histogram[ pixVal ]++;
} // pix
}
}
}
This is the class where I wish to create the button which will create the histogram:
public class testrgb extends Activity {
/************************
* PROPERTIES
**********************/
/* Tag for Log */
public static final String TAG = "PiccaFinal.EditPicturesActivity";
/* Images Path */
private String[] _imagesPath;
/* Original Images */
private Bitmap[] _originalBitmaps = new Bitmap[2];
/* Final Filtered Images */
private Bitmap[] _filteredBitmaps = new Bitmap[2];
/* Image View */
private ImageView _filterImageView;
private Preview mPreview;
private DrawOnTop mDrawOnTop;
int[] pixels;
/************************
* ANDROID METHODS
**********************/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_edit_pictures);
Intent intent = getIntent();
_imagesPath = intent.getStringArrayExtra(MainActivity.IMAGES_PATH);
for (int i = MainActivity.LEFT_IMAGE; i <= MainActivity.RIGHT_IMAGE; i++) {
_originalBitmaps[i] = BitmapFactory.decodeFile(_imagesPath[i]);
}
_filterImageView = (ImageView) findViewById(R.id.filter_image_view);
_filterImageView
.setImageBitmap(_originalBitmaps[MainActivity.LEFT_IMAGE]);
// --------------------------------------------------------------------------------
// display_RGB
Button display_RGBButton = (Button) findViewById(R.id.display_RGB);
display_RGBButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//what should I do here
});
}
}
I'm working on some exercises and I've been stuck on this for some hours now (quite new to Java).
Anyhow, this is what I'm supposed to do:
When I run the program I will have a square in the middle of the screen and when I then click somewhere within that screen another square will be drawn at the place where I clicked and in-between these two points there are supposed to be 10 squares. So wherever I click there should always be 10 squares drawn between.
However, I can't make it to function properly.
This is what I've managed to do so far:
import se.lth.cs.ptdc.window.SimpleWindow;
import se.lth.cs.ptdc.square.Square;
public class PrintSquares2 {
public static void main(String[] args) {
SimpleWindow w = new SimpleWindow(600, 600, "PrintSquares2");
int posX = 300;
int posY = 300;
int loop = 0;
System.out.println("Skriv rotation");
Square sq1 = new Square(posX,posY,200);
sq1.draw(w);
w.waitForMouseClick();
int destX = w.getMouseX();
int destY = w.getMouseY();
System.out.println("Dest X: " + destX + " Dest Y: " + destY);
System.out.println("Pos X: " + posX + " Pos Y: " + posY);
SimpleWindow.delay(10);
//sq1.erase(w);
int jumpX = (destX - posX) / 10;
int jumpY = (destY - posY) / 10;
System.out.println(jumpX);
while (posX < destX)
{
posX = posX+10;
SimpleWindow.delay(100);
loop++;
System.out.println("Loop: " + loop);
System.out.println("Dest X: " + destX + " Dest Y: " + destY);
System.out.println("Pos X: " + posX + " Pos Y: " + posY);
Square sq2 = new Square(posX,posY,200);
sq2.draw(w);
}
while (posX > destX)
{
posX = posX-10;
SimpleWindow.delay(100);
loop++;
System.out.println("Loop: " + loop);
System.out.println("Dest X: " + destX + " Dest Y: " + destY);
System.out.println("Pos X: " + posX + " Pos Y: " + posY);
sq1.draw(w);
Square sq2 = new Square(posX,posY,200);
sq2.draw(w);
}
while (posY < destY)
{
posY = posY+10;
SimpleWindow.delay(100);
loop++;
System.out.println("Loop: " + loop);
System.out.println("Dest X: " + destX + " Dest Y: " + destY);
System.out.println("Pos X: " + posX + " Pos Y: " + posY);
sq1.draw(w);
Square sq2 = new Square(posX,posY,200);
sq2.draw(w);
}
while (posY > destY)
{
posY = posY-10;
SimpleWindow.delay(100);
loop++;
System.out.println("Loop: " + loop);
System.out.println("Dest X: " + destX + " Dest Y: " + destY);
System.out.println("Pos X: " + posX + " Pos Y: " + posY);
sq1.draw(w);
Square sq2 = new Square(posX,posY,200);
sq2.draw(w);
}
SimpleWindow.delay(10);
sq1.draw(w);
//SimpleWindow.clear(w);
}
}
I'm pretty sure that I overcomplicated everything since this should be pretty basic.
The end result is supposed to look like this:
End result
This is the way I'd have solved it:
I didn't quite understand the documentation on se.lth.cs.ptdc.square.Square but I'll assume it draws a square given the coordinates of its top-left corner and a side size.
So you have the coodinates of your first square's left-top corner and the coordinates of the last square's center. Having that it's not difficult to get the coords of the last square's top-left corner:
lastX = centerX - side/2
lastY = centerY - side/2
After you have that you find the difference between the starting and ending points:
diffX = posX - lastX
diffY = posY - lastY
and after that just draw 9 more squares:
for (int i=1; i<10; i++){
squareX = posX + (diffX/10)*i;
squareY = posY + (diffY/10)*i;
Square square = new Square(squareX,squareY,200);
square.draw(w);
}
Actually you did the first part right, just messed up with those unnecessary checks. Hope it helps.
--
Regards, svz.
Update both X and Y at the SAME time :
int jumpX = (destX - posX) / 10;
int jumpY = (destY - posY) / 10;
if (posX > destX) {
int temp = destX;
destX = posX;
posX = temp;
}
while (posX <= destX)
{
SimpleWindow.delay(100);
loop++;
System.out.println("Loop: " + loop);
System.out.println("Dest X: " + destX + " Dest Y: " + destY);
System.out.println("Pos X: " + posX + " Pos Y: " + posY);
Square sq2 = new Square(posX,posY,200);
sq2.draw(w);
posX = posX+jumpX;
posY = posY+jumpY;
}
SimpleWindow.delay(10);
sq1.draw(w);
Here's how you move in two directions at once (on a diagonal).
static final int Steps = 10;
private void test() {
int x1 = 100;
int y1 = 100;
int x2 = 300;
int y2 = 500;
double dx = (double)(x2 - x1) / (double) Steps;
double dy = (double)(y2 - y1) / (double) Steps;
double x = x1;
double y = x2;
for ( int i = 0; i < Steps; i++) {
// Simulate the drawing of the square.
System.out.println("("+x+","+y+")");
x += dx;
y += dy;
}
}