I am trying to fill a grid with duplicates of one rectangle filled with white noise.
I can create a grid with rectangle but can't fill them with noise. I can create white noise but can't fill a grid with it. Below the attempt to create the original. Now I would like to duplicate this in a e.g, 3x3 grid
void setup(){
size(900,900);
background(0);
stroke(255);
noFill();
noiseDetail(5);
println(pixelWidth, pixelHeight);
}
void draw(){
background(0);
float scale = 0.01;
int w = 300;
int h = 300;
loadPixels();
for(int x = 0; x<w;x++){
for(int y = 0; y<h;y++){
float col = 255*noise(scale*x,scale*y,30*scale*frameCount);
pixels[x + y*900] = color(col);
}
}
updatePixels();
}
The result is a 300x300 rectangle filled with noise. I would like to have 9 of those in a grid with the same identical white noise.
I recommend to write a function, which renders the noise tile to PGraphics object:
PGraphics CreateTile(int w, int h, float scale)
{
PGraphics pg = createGraphics(w, h, JAVA2D);
pg.beginDraw();
for(int x = 0; x<w;x++){
for(int y = 0; y<h;y++){
float col = 255*noise(scale * x, scale * y, 30 * scale * frameCount);
pg.set(x, y, color(col));
}
}
pg.endDraw();
return pg;
}
Then you can place the tile as often as you want you want:
void draw(){
background(0);
int w = 300;
int h = 300;
PGraphics pg = CreateTile(w, h, 0.01);
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
image(pg, w*i, h*j);
}
}
}
Related
I need to implement image blur
to do this, I have to use a double array in the form of a matrix, and implement the following:
each coefficient of the convolution matrix must be multiplied by the color value of the corresponding neighbor of the current (changeable) pixel
I need to handle going beyond 0 to 255
I tried to create and fill in the matrix with the 1/9 numbers that are in the task, but then I don't understand what and by what should I multiply?
has anyone solved this?
public static void main(String[] args) throws IOException {
BufferedImage image = ImageIO.read(new File("image.jpg"));
WritableRaster raster = image.getRaster();
int width = raster.getWidth();
int height = raster.getHeight();
final int colorsCountInRgb = 3;
final int colorMaximum = 255;
int[] pixel = new int[colorsCountInRgb];
double[][] matrix = new double[3][3];
double matrixMultiplier = 1 / 9d;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix.length; j++) {
matrix[i][j] = matrixMultiplier;
}
}
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
raster.getPixel(x, y, pixel);
raster.setPixel(x, y, pixel);
}
}
ImageIO.write(image, "png", new File("out.png"));
}
I have a homework task where I have to write a class responsible for contour detection. It is essentially an image processing operation, using the definition of euclidean distance between 2 points in the 3-dimensional space. Formula given to us to use is:
Math.sqrt(Math.pow(pix1.red - pix2.red,2) + Math.pow(pix1.green- pix2.green,2) + Math.pow(pix1.blue- pix2.blue,2));
We need to consider each entry of the two dimensional array storing the colors of the pixels of an image, and if some pixel, pix, the color distance between p and any of its neighbors is more than 70, change the color of the pixel to black, else change it to white.
We are given a seperate class as well responsible for choosing an image, and selecting an output, for which method operationContouring is applied to. Java syntax and convention is very new to me having started with python. Conceptually, I'm struggling to understand what the difference between pix1 and pix2 is, and how to define them. This is my code so far.
Given:
import java.awt.Color;
/* Interface for ensuring all image operations invoked in same manner */
public interface operationImage {
public Color[][] operationDo(Color[][] imageArray);
}
My code:
import java.awt.Color;
public class operationContouring implements operationImage {
public Color[][] operationDo(Color[][] imageArray) {
int numberOfRows = imageArray.length;
int numberOfColumns = imageArray[0].length;
Color[][] results = new Color[numberOfRows][numberOfColumns];
for (int i = 0; i < numberOfRows; i++)
for (int j = 0; j < numberOfColumns; j++) {
int red = imageArray[i][j].getRed();
int green = imageArray[i][j].getGreen();
int blue = imageArray[i][j].getBlue();
double DistanceColor = Math.sqrt(Math.pow(pix1.red - pix2.red,2) + Math.pow(pix1.green- pix2.green,2) + Math.pow(pix1.blue- pix2.blue,2));
int LIMIT = 70;
if (DistanceColor> LIMIT ) {
results[i][j] = new Color((red=0), (green=0), (blue=0));
}
else {
results[i][j] = new Color((red=255), (green=255), (blue=255));
}
}
return results;
}
}
This is a solution I wrote that uses BufferedImages. I tested it and it should work. Try changing it such that it uses your data format (Color[][]) and it should work for you too. Note that "pix1" is nothing more than a description of the color of some pixel, and "pix2" is the description of the color of the pixel you are comparing it to (determining whether the color distance > 70).
public static boolean tooDifferent(Color c1, Color c2) {
return Math.sqrt(Math.pow(c1.getRed() - c2.getRed(),2) + Math.pow(c1.getGreen()- c2.getGreen(),2) + Math.pow(c1.getBlue()- c2.getBlue(),2)) > 70;
}
public static Color getColor(int x, int y, BufferedImage img) {
return new Color(img.getRGB(x, y));
}
public static BufferedImage operationDo(BufferedImage img) {
int numberOfRows = img.getHeight();
int numberOfColumns = img.getWidth();
BufferedImage results = new BufferedImage(numberOfColumns, numberOfRows, BufferedImage.TYPE_INT_ARGB);
for (int y = 0; y < numberOfRows; y++) {
for (int x = 0; x < numberOfColumns; x++) {
Color color = new Color(img.getRGB(x, y));
boolean aboveExists = y > 0;
boolean belowExists = y < numberOfRows - 1;
boolean leftExists = x > 0;
boolean rightExists = x < numberOfColumns - 1;
if ((aboveExists && tooDifferent(color, getColor(x, y - 1, img))) ||
(belowExists && tooDifferent(color, getColor(x, y + 1, img))) ||
(leftExists && tooDifferent(color, getColor(x - 1, y, img))) ||
(rightExists && tooDifferent(color, getColor(x + 1, y, img)))) {
results.setRGB(x, y, Color.black.getRGB());
} else {
results.setRGB(x, y, Color.white.getRGB());
}
}
}
return results;
}
I am trying to write a function that overlays an image at a rectangle with transparency over top of another image, However it doesn't layer the images it just erases the section that I overlay and the transparency cuts through the entire image. Here is my code.
public static void overlayImage(String imagePath, String overlayPath, int x, int y, int width, int height) {
Mat overlay = Imgcodecs.imread(overlayPath, Imgcodecs.IMREAD_UNCHANGED);
Mat image = Imgcodecs.imread(imagePath, Imgcodecs.IMREAD_UNCHANGED);
Rectangle rect = new Rectangle(x, y, width, height);
Imgproc.resize(overlay, overlay, rect.size());
Mat submat = image.submat(new Rect(rect.x, rect.y, overlay.cols(), overlay.rows()));
overlay.copyTo(submat);
Imgcodecs.imwrite(imagePath, image);
}
EDIT: Here are some example pictures:
Before:
After:
Found this function that does exactly what I needed.
public static void overlayImage(Mat background,Mat foreground,Mat output, Point location){
background.copyTo(output);
for(int y = (int) Math.max(location.y , 0); y < background.rows(); ++y){
int fY = (int) (y - location.y);
if(fY >= foreground.rows())
break;
for(int x = (int) Math.max(location.x, 0); x < background.cols(); ++x){
int fX = (int) (x - location.x);
if(fX >= foreground.cols()){
break;
}
double opacity;
double[] finalPixelValue = new double[4];
opacity = foreground.get(fY , fX)[3];
finalPixelValue[0] = background.get(y, x)[0];
finalPixelValue[1] = background.get(y, x)[1];
finalPixelValue[2] = background.get(y, x)[2];
finalPixelValue[3] = background.get(y, x)[3];
for(int c = 0; c < output.channels(); ++c){
if(opacity > 0){
double foregroundPx = foreground.get(fY, fX)[c];
double backgroundPx = background.get(y, x)[c];
float fOpacity = (float) (opacity / 255);
finalPixelValue[c] = ((backgroundPx * ( 1.0 - fOpacity)) + (foregroundPx * fOpacity));
if(c==3){
finalPixelValue[c] = foreground.get(fY,fX)[3];
}
}
}
output.put(y, x,finalPixelValue);
}
}
}
HiI was wondering how to flip and image horizontally, for a practce task I was given a code that reads an image, inverting it to an image indicating it's brightness from 0-5, I had to flip an image.
This is my code of my reading an image and drawing it
public int[][] readImage(String url) throws IOException
{
// fetch the image
BufferedImage img = ImageIO.read(new URL(url));
// create the array to match the dimensions of the image
int width = img.getWidth();
int height = img.getHeight();
int[][] imageArray = new int[width][height];
// convert the pixels of the image into brightness values
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
// get the pixel at (x,y)
int rgb = img.getRGB(x,y);
Color c = new Color(rgb);
int red = c.getRed();
int green = c.getGreen();
int blue = c.getBlue();
// convert to greyscale
float[] hsb = Color.RGBtoHSB(red, green, blue, null);
int brightness = (int)Math.round(hsb[2] * (PIXEL_CHARS.length - 1));
imageArray[x][y] = brightness;
}
}
return imageArray;
}
public void draw() throws IOException
{
int[][] array = readImage("http://sfpl.org/images/graphics/chicklets/google-small.png");
for(int i=0; i<array.length; i++)
{
for(int pic=0; pic<array[i].length; pic++)
{
if(array[pic][i] == 0)
{
System.out.print("X");
}
else if(array[pic][i] == 1)
{
System.out.print("8");
}
else if(array[pic][i] == 2)
{
System.out.print("0");
}
else if(array[pic][i] == 3)
{
System.out.print(":");
}
else if(array[pic][i] == 4)
{
System.out.print(".");
}
else if (array[pic][i] == 5)
{
System.out.print(" ");
}
else
{
System.out.print("error");
break;
}
}
System.out.println();
}
}
and this is the code I tried to create to horizontally flip it,
void mirrorUpDown()
{
int[][] array = readImage("http://sfpl.org/images/graphics/chicklets/google-small.png");
int i = 0;
for (int x = 0; x < array.length; x++)
{
for (int y = 0; y < array[i].length; y++)
{{
int temp = array[x][y];
array[x][y]= array[-x][y];
array[array[i].length-x][y]=temp;
}
}
}
}
I get an error
unreported exception java.io.IException;
must be caught or declared to be thrown
I'd actually do it by this way...
BufferedImage flip(BufferedImage sprite){
BufferedImage img = new BufferedImage(sprite.getWidth(),sprite.getHeight(),BufferedImage.TYPE_INT_ARGB);
for(int xx = sprite.getWidth()-1;xx>0;xx--){
for(int yy = 0;yy < sprite.getHeight();yy++){
img.setRGB(sprite.getWidth()-xx, yy, sprite.getRGB(xx, yy));
}
}
return img;
}
Just a loop whose x starts at the end of the first image and places its rgba value on the flipped position of the second image. Clean, easy code :)
The function mirrorUpDown() , add a throws IOException there.
Also the function from which you are calling these methods, does that handle exception, does that code enclosed in a try catch block or the function is also set to throw IOException (one of either should be there)
How is your image supposed to know it should get it's data from imageArray ?
instead, you should access the raster of your image and modify the data in it.
void flip(BufferedImage image) {
WritableRaster raster = image.getRaster();
int h = raster.getHeight();
int w = raster.getWidth();
int x0 = raster.getMinX();
int y0 = raster.getMinY();
for (int x = x0; x < x0 + w; x++){
for (int y = y0; y < y0 + h / 2; y++){
int[] pix1 = new int[3];
pix1 = raster.getPixel(x, y, pix1);
int[] pix2 = new int[3];
pix2 = raster.getPixel(x, y0 + h - 1 - (y - y0), pix2);
raster.setPixel(x, y, pix2);
raster.setPixel(x, y0 + h - 1 - (y - y0), pix1);
}
}
return;
}
Sorry about posting this here over a year later but it should aid someone at a stage
try{
java.awt.image.BufferedImage bi = javax.imageio.ImageIO.read(getClass().getResource("Your image bro.jpg")) ;
int[] h = bi.getRGB(0, 0, bi.getWidth(), bi.getHeight(), null, 0, bi.getWidth());
int [] h1 = new int[h.length];
System.out.println(""+h.length);
for(int j = 0;500>j;j++){
for(int i = 500;i>0;i--){
h1[j*500+(500-i)] = h[(j*500)+(i-1)];
}
}
bi.setRGB(0, 0, bi.getWidth(), bi.getHeight(), h1, 0, bi.getWidth());
}
catch(Exception e){e.printStackTrace();}
Lets break the code down
java.awt.image.BufferedImage bi =javax.imageio.ImageIO.read(getClass().getResource("Your image bro.jpg"));
Tries to read the image and stores the read image into the BufferedImage variable bi
int[] h = bi.getRGB(0, 0, bi.getWidth(), bi.getHeight(), null, 0, bi.getWidth());
int [] h1 = new int[h.length];
instantiate two arrays, h is the original RGB Array and h1 will be the horizontally flipped RGB array.
for(int j = 0;500>j;j++){
for(int i = 500;i>0;i--){
h1[j*500+(500-i)] = h[(j*500)+(i-1)];
}
}
Lets look at something in particular more closely
h1[j*500+(500-i)] = h[(j*500)+(i-1)];
Images are scanned from position 0;0 to x.length;y.length
but it is scanned in a coninual array. Thus we use a psuedo-array to manipulate the flipping of the image. j*500 references the Y values and (500-i) references the x values.
bi.setRGB(0, 0, bi.getWidth(), bi.getHeight(), h1, 0, bi.getWidth());
Finally, the image gets stored back into the BufferedImage variable.
Note that the 500 constant is referencing your x resolution of the image. For example, 1920 x 1080 sized image uses a max value of 1920. The logic is yours to decide.
In the body of the Picture class create a new public method named "specialEffect" that has return type void and takes no parameters.
The method should contain four loops that each iterate over the pixels of an image in such a way that each loop iterates through 1/4 of the total number of pixels and performs a different effect as follows:
The first loop is to apply an effect that removes the both the blue and green component from each pixel leaving the red component unchanged.
The next loop continuing from where the last left off is to remove the blue and red component from each pixel leaving the green component unchanged.
The next loop continuing from where the last left off it to remove the green and red component from each pixel leaving the blue component unchanged.
The final loop continuing from where the last off is to convert each pixel to greyscale.
How would I go about doing that? I only know how to divide it in half and change the top part.. not sure how to go about doing sections.
Thanks!
The code below produces this picture:
private static BufferedImage specialEffect(BufferedImage in) {
BufferedImage out = new BufferedImage(in.getWidth(), in.getHeight(),
BufferedImage.TYPE_INT_ARGB);
for (int x = 0; x < out.getWidth() / 2; x++) {
for (int y = 0; y < out.getHeight() / 2; y++) {
Color c = new Color(in.getRGB(x, y));
out.setRGB(x, y, new Color(c.getRed(), 0, 0).getRGB());
}
}
for (int x = out.getWidth() / 2; x < out.getWidth(); x++) {
for (int y = 0; y < out.getHeight() / 2; y++) {
Color c = new Color(in.getRGB(x, y));
out.setRGB(x, y, new Color(0, c.getGreen(), 0).getRGB());
}
}
for (int x = 0; x < out.getWidth() / 2; x++) {
for (int y = out.getHeight() / 2; y < out.getHeight(); y++) {
Color c = new Color(in.getRGB(x, y));
out.setRGB(x, y, new Color(0, 0, c.getBlue()).getRGB());
}
}
for (int x = out.getWidth() / 2; x < out.getWidth(); x++) {
for (int y = out.getHeight() / 2; y < out.getHeight(); y++) {
Color c = new Color(in.getRGB(x, y));
int m = Math.max(c.getRed(),Math.max(c.getGreen(),c.getBlue()));
out.setRGB(x, y, new Color(m, m, m).getRGB());
}
}
return out;
}
public static void main(String[] args) throws IOException {
JFrame frame = new JFrame("Test");
frame.add(new JComponent() {
BufferedImage image = specialEffect(ImageIO.read(new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png")));
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}
I am assuming that your Picture class has the following methods:
int getNumberOfPixels()
float getRValueOfNthPixel(int n)
float getGValueOfNthPixel(int n)
float getBValueOfNthPixel(int n)
void setRValueOfNthPixel(int n, float r)
void setGValueOfNthPixel(int n, float g)
void setBValueOfNthPixel(int n, float b)
If the number of pixels is always a multiple of 4, then one possible implementation of "specialEffect" method would be:
public void specialEffect() {
int n = getNumberOfPixels();
int limit1 = 1 * n / 4;
int limit2 = 2 * n / 4;
int limit3 = 3 * n / 4;
int limit4 = 4 * n / 4;
/*
* The first loop is to apply an effect that removes the both the blue
* and green component from each pixel leaving the red component
* unchanged.
*/
for (int i = 0; i < limit1; i++) {
setBValueOfNthPixel(i, 0);
setGValueOfNthPixel(i, 0);
}
/*
* The next loop continuing from where the last left off is to remove
* the blue and red component from each pixel leaving the green
* component unchanged.
*/
for (int i = limit1; i < limit2; i++) {
setBValueOfNthPixel(i, 0);
setRValueOfNthPixel(i, 0);
}
/*
* The next loop continuing from where the last left off it to remove
* the green and red component from each pixel leaving the blue
* component unchanged.
*/
for (int i = limit2; i < limit3; i++) {
setGValueOfNthPixel(i, 0);
setRValueOfNthPixel(i, 0);
}
/*
* The final loop continuing from where the last off is to convert each
* pixel to greyscale.
*/
for (int i = limit3; i < limit4; i++) {
float grayValue = (getRValueOfNthPixel(i)
+ getGValueOfNthPixel(i)
+ getBValueOfNthPixel(i)) / 3;
setRValueOfNthPixel(i, grayValue);
setGValueOfNthPixel(i, grayValue);
setBValueOfNthPixel(i, grayValue);
}
}