[JAVA] Mandels to create an image of the Mandelbrot set

Introduction

As a practice of manipulating pixels in image processing, I made an image of the Mandelbrot set (see Wikipedia for details). Java gives you the big picture, and C # and C ++ give you an image of the appropriately enlarged part. Basically, it seems faster to write directly to the internal array than to use a method like ʻimage.setPixel (i, j, color)`.

Java Whereas C # and C ++ are arranged for each channel, Java is an element that combines ARGB into one 32-bit integer.

import java.awt.Color;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;

public class Mandelbrot{
    public static final int WIDTH = 1000;
    public static final int HEIGHT = 1000;
        
    public static void main(String[] args){
		int[] pixels = new int[WIDTH*HEIGHT];
		for(int i = 0; i < WIDTH; i++){
			for(int j = 0; j < HEIGHT; j++){
				pixels[WIDTH*j+i] = calcMandelbrot(i, j);
			}
		}
		BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
		image.setRGB(0, 0, WIDTH, HEIGHT, pixels, 0, WIDTH);
		File file = new File("mandelbrot.png ");
		try{
			ImageIO.write(image, "png", file);
		}catch(IOException e){
			System.out.println(e);
		}
	}
	
	//Mandelbrot set parameters
    public static final double xMin = -2.1;
    public static final double xMax = 0.5;
    public static final double yMin = -1.3;
    public static final double yMax = 1.3;
    public static final int nMax = 300;
     
    //point(i, j)Calculate the color for AHSV
	public static int calcMandelbrot(int i, int j){
		final double c = xMin+i*(xMax-xMin)/WIDTH;
		final double d = yMin+j*(yMax-yMin)/HEIGHT;
        double x1 = 0.0, y1 = 0.0, x2, y2;
        int n = 0;
        for(n = 0; n < nMax; n++){
            x2 = x1*x1-y1*y1+c;
            y2 = 2*x1*y1+d;
            if(x2*x2+y2*y2 > 4.0) break;
            x1 = x2;
            y1 = y2;
        }
		final float t = (float)n/nMax;
		if(t >= 1.0f){
			return 0xff000000; //black
		}else{
			return 0xff000000 | Color.HSBtoRGB(t, 0.6f, 1.0f);
		}
	}
}

result: mandelbrot1.png

Reference: [Manipulating image pixels with Java | Naberogu](https://www.google.co.jp/url?sa=t&rct=j&q=1esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwi5s -2q-4XSAhWKgrwKHYoDAugQFggaMAA & url = http% 3A% 2F% 2Fblog.nabe-ch.net% 2F% 3Fp% 3D532 & usg = AFQjCNHl-RIE4VzT1sbyfrpzRNMPOLTUeA & sig2 = ckRLdb2H-aPog

C# It seems that there is no conversion between HSV and RGB in C #, so Wikipedia I made it with reference to.

using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace Mandelbrot{
    static class Program{
        public const int WIDTH = 1000;
        public const int HEIGHT = 1000;

        public static void Main(string[] args){
            Bitmap image = new Bitmap(WIDTH, HEIGHT, PixelFormat.Format32bppArgb);
            BitmapData data = image.LockBits(
                new Rectangle(0, 0, WIDTH, HEIGHT),
                ImageLockMode.WriteOnly,
                PixelFormat.Format32bppArgb);
            byte[] buf = new byte[4*WIDTH*HEIGHT];
            for(int i = 0; i < WIDTH; i++){
                for(int j = 0; j < HEIGHT; j++){
                    byte a = 0, r = 0, g = 0, b = 0;
                    CalcMandelbrot(i, j, ref a, ref r, ref g, ref b);
                    buf[4*(WIDTH*j+i)+3] = a;
                    buf[4*(WIDTH*j+i)+2] = r;
                    buf[4*(WIDTH*j+i)+1] = g;
                    buf[4*(WIDTH*j+i)] = b;
                }
            }
            System.Runtime.InteropServices.Marshal.Copy(buf, 0, data.Scan0, buf.Length);
            image.UnlockBits(data);
            image.Save("mandelbrot.png ");
        }
        
        //Mandelbrot set parameters
        public const double xMin = -0.7406219098542647;
        public const double xMax = -0.7406219098519411;
        public const double yMin = 0.15805475052205210;
        public const double yMax = 0.15805475052421664;
        public const int nMax = 18000;
        
        //point(i, j)Calculate the color for AHSV
        public static void CalcMandelbrot(int i, int j, ref byte a, ref byte r, ref byte g, ref byte b){
            double c = xMin+i*(xMax-xMin)/WIDTH;
            double d = yMin+j*(yMax-yMin)/HEIGHT;
            double x1 = 0.0, y1 = 0.0, x2, y2;
            int n = 0;
            for(n = 0; n < nMax; n++){
                x2 = x1*x1-y1*y1+c;
                y2 = 2*x1*y1+d;
                if(x2*x2+y2*y2 > 4.0) break;
                x1 = x2;
                y1 = y2;
            }
            double t = (double)n/nMax;
            if(t >= 1.0){
                a = 0xff;
                r = g = b = 0; //black
            }else{
                ARGBfromAHSV(ref a, ref r, ref g, ref b, 1.0, 0.55, 0.3+0.3*Math.Sin(12*Math.PI*t), 0.7+0.3*Math.Cos(16*Math.PI*t));
            }
        }
        
        //Convert from ARGB to AHSV
        public static void ARGBfromAHSV(ref byte aOut, ref byte r, ref byte g, ref byte b, double aIn, double h, double s, double v){
            aOut = (byte)(255*aIn);
            r = (byte)(255*v);
            g = (byte)(255*v);
            b = (byte)(255*v);
            if (s <= 0.0) return;
            h *= 6.0;
            int i = (int)h;
            double f = h-i;
            switch(i){
                case 0:
                    g = (byte)(g*(1-s*(1-f)));
                    b = (byte)(b*(1-s));
                    break;
                case 1:
                    r = (byte)(r*(1-s*f));
                    b = (byte)(b*(1-s));
                    break;
                case 2:
                    r = (byte)(r*(1-s));
                    b = (byte)(b*(1-s*(1-f)));
                    break;
                case 3:
                    r = (byte)(r*(1-s));
                    g = (byte)(g*(1-s*f));
                    break;
                case 4:
                    r = (byte)(r*(1-s*(1-f)));
                    g = (byte)(g*(1-s));
                    break;
                case 5:
                    g = (byte)(g*(1-s));
                    b = (byte)(b*(1-s*f));
                    break;
            }
        }
    }
}

result: mandelbrot2.png

Reference: [[C #] How to access bitmaps in pixels at high speed (GetPixel / SetPixel vs BitmapData speed comparison)](http://www.84kure.com/blog/2014/07/13/c-% E3% 83% 93% E3% 83% 83% E3% 83% 88% E3% 83% 9E% E3% 83% 83% E3% 83% 97% E3% 81% AB% E3% 83% 94% E3% 82% AF% E3% 82% BB% E3% 83% AB% E5% 8D% 98% E4% BD% 8D% E3% 81% A7% E9% AB% 98% E9% 80% 9F% E3% 81% AB% E3% 82% A2% E3% 82% AF% E3% 82% BB% E3% 82% B9 /)

C++ I used OpenCV. This time it's all opaque so it doesn't make any sense, but it seems that OpenCV cannot convert between HSV and RGB when alpha value is included (c ++ --OpenCV cv :: cvtColor drops alpha channel, How to keep alpha data?).

#include <cmath>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>

void calcMandelbrot(int i, int j, unsigned char& h, unsigned char& s, unsigned char& v);

constexpr int width = 1000;
constexpr int height = 1000;

int main(){
	cv::Mat image(height, width, CV_8UC3);
	for(int i = 0; i < width; i++){
		for(int j = 0; j < height; j++){
			unsigned char h, s, v;
			calcMandelbrot(i, j, h, s, v);
			image.data[3*(width*j+i)] = h;
			image.data[3*(width*j+i)+1] = s;
			image.data[3*(width*j+i)+2] = v;
		}
	}
	cv::cvtColor(image, image, CV_HSV2RGB);
	cv::imwrite("mandelbrot.png ", image);
	return 0;
}

//Mandelbrot set parameters
constexpr double xMin = -1.4467108885212991;
constexpr double xMax = -1.4467096751794892;
constexpr double yMin = -1.3212921606783162e-5;
constexpr double yMax = -1.2078843332240347e-5;
constexpr int nMax = 1000;

//point(i, j)Calculate the color for HSV
//The range of h is from 0 to 180
void calcMandelbrot(int i, int j, unsigned char& h, unsigned char& s, unsigned char& v){
	const double c = xMin+i*(xMax-xMin)/width;
	const double d = yMin+j*(yMax-yMin)/height;
	double x1 = 0.0, y1 = 0.0, x2, y2;
	int n = 0;
	for(n = 0; n < nMax; n++){
		x2 = x1*x1-y1*y1+c;
		y2 = 2*x1*y1+d;
		if(x2*x2+y2*y2 > 4.0) break;
		x1 = x2;
		y1 = y2;
	}
	const double t = static_cast<double>(n)/nMax;
	if(t >= 1.0){
		h = s = v = 0; //black
	}else{
		h = static_cast<unsigned char>(180*0.3);
		s = static_cast<unsigned char>(255*(0.3+0.3*sin(12*M_PI*t)));
		v = static_cast<unsigned char>(255*(0.7+0.3*cos(16*M_PI*t)));
	}
}

result: mandelbrot3.png

reference: ・ Learning OpenCV 2 -Count green pixels

Recommended Posts

Mandels to create an image of the Mandelbrot set
[Swift] How to set an image in the background without using UIImageView.
Easy way to create an implementation of java.util.stream.Stream
Set the time of LocalDateTime to a specific time
How to set an image in the drawable Left / Right of a button using an icon font (Iconics)
How to judge the click of any area of the image
[Rails] How to display an image in the view
How to create an application
[Swift5] How to get an array and the complement of arrays
How to set the IP address and host name of CentOS8
[Swift] Set the Style of TableViewCell to something other than Custom
Fix the file name of war to the one set in Maven
The story of toString () starting with passing an array to System.out.println
[Android Studio] Set an arbitrary image for the application background [Java]
The milliseconds to set in /lib/calendars.properties of Java jre is UTC
How to get the length of an audio file in java
How to set the indent to 2 single-byte spaces in the JAXB implementation of the JDK
How to convert an array of Strings to an array of objects with the Stream API
Get the type of an array element to determine if it is an array
Change the save destination of the image to S3 in the Rails app. Part 2
How to crop an image with libGDX
Display text on top of the image
About the version of Docker's Node.js image
Display an image on the base64 screen
How to blur an image (super easy)
Compare the elements of an array (Java)
[Java] How to set the Date time to 00:00:00
Convert an array of strings to numbers
How to sort the List of SelectItem
Output of the book "Introduction to Java"
The process of introducing Vuetify to Rails
[Swift] How to get the number of elements in an array (super basic)
Let's capture the image of the IP camera to the OKI AI edge computer "AE2100"
Try adding text to an image in Scala using the Java standard library
How to create a small docker image of openjdk 11 (ea) application (1GB → 85MB)
Create your own shortcuts in Xcode to eliminate the hassle of pod install
How to set environment variables in the properties file of Spring boot application
[Order method] Set the order of data in Rails
How to find the cause of the Ruby error
I want to output the day of the week
[Rails] Button to return to the top of the page
Customize how to divide the contents of Recyclerview
Make a margin to the left of the TextField
I want to var_dump the contents of the intent
How to get today's day of the week
Change the timezone of the https-portal container to JST
[Ruby] Code to display the day of the week
[Java] (for MacOS) How to set the classpath
Create an app by specifying the Rails version
Rails6.0 ~ How to create an eco-friendly development environment
[Java / Kotlin] Resize considering the orientation of the image
The story of adding the latest Node.js to DockerFile
I tried to set tomcat to run the Servlet.
How to display the result of form input
Change the location folder of Docker image & container
[Swift] Create an image selection UI with PhotoKit
Push the image to docker hub using Jib
[Java] How to get the authority of the folder
How to create an oleore certificate (SSL certificate, self-signed certificate)
Java Welcome to the Swamp of 2D Arrays
[Android development] Get an image from the server in Java and set it in ImageView! !!