[JAVA] Manipulez les pixels pour créer une image d'un ensemble de Mandelbrot

introduction

Comme pratique de manipulation des pixels dans le traitement d'image, j'ai créé une image de l'ensemble de Mandelbrot (voir Wikipedia pour plus de détails). Java vous donne une vue d'ensemble, et C # et C ++ vous donnent une image de la pièce correctement agrandie. Fondamentalement, il semble plus rapide d'écrire directement dans le tableau interne que d'utiliser une méthode comme ʻimage.setPixel (i, j, color) `.

Java Alors que C # et C ++ sont arrangés pour chaque canal, Java est un élément qui combine ARVB en un entier 32 bits.

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 définit les paramètres
    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)Calculer la couleur pour 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);
		}
	}
}

résultat: mandelbrot1.png

Référence: [Manipulation des pixels d'image avec 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 = ckRLdbb

C# Il semble qu'il n'y ait pas de conversion entre HSV et RVB en C #, donc Wikipedia Je l'ai fait en référence à.

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 définit les paramètres
        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)Calculer la couleur pour 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));
            }
        }
        
        //Convertir ARGB en 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;
            }
        }
    }
}

résultat: mandelbrot2.png

Référence: [[C #] Comment accéder à Bitmap à haute vitesse pixel par pixel (comparaison de vitesse GetPixel / SetPixel vs BitmapData)](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++ J'ai utilisé OpenCV. Cette fois, tout est opaque, donc cela n'a aucun sens, mais il semble qu'OpenCV ne puisse pas convertir entre HSV et RGB lorsque les valeurs alpha sont incluses (c ++ --OpenCV cv :: cvtColor supprime le canal alpha, Comment conserver les données alpha?).

#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 définit les paramètres
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)Calculer la couleur pour HSV
//La plage de h va de 0 à 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)));
	}
}

résultat: mandelbrot3.png

référence: ・ Apprendre OpenCV 2

Recommended Posts

Manipulez les pixels pour créer une image d'un ensemble de Mandelbrot
Un moyen simple de créer une implémentation de java.util.stream.Stream
Définir l'heure de LocalDateTime à une heure spécifique
Comment définir l'image pour dessiner à gauche / à droite du bouton à l'aide de la police d'icône (Iconics)
Comment juger le clic de n'importe quelle zone de l'image
[Rails] Comment afficher les images dans la vue
[Swift5] Comment obtenir un tableau et un ensemble de différences entre les tableaux
Comment définir l'adresse IP et le nom d'hôte de CentOS8
Fixez le nom du fichier de guerre à celui défini dans Maven
L'histoire de toString () commençant par le passage d'un tableau à System.out.println
[Android Studio] Définir une image arbitraire pour l'arrière-plan de l'application [Java]
La milliseconde définie dans /lib/calendars.properties de Java jre est UTC
Comment obtenir la longueur d'un fichier audio avec Java
Comment créer un retrait de deux espaces d'un octet dans l'implémentation JAXB du JDK
Comment convertir un tableau de chaînes en un tableau d'objets avec l'API Stream
Obtenez le type d'un élément d'un tableau pour déterminer s'il s'agit d'un tableau
Modifiez la destination d'enregistrement de l'image en S3 dans l'application Rails. Partie 2
Comment recadrer une image avec libGDX
Afficher le texte en haut de l'image
Comment brouiller l'image (super facile)
Comparer les éléments d'un tableau (Java)
[Java] Comment régler la date sur 00:00:00
Convertir un tableau de chaînes en nombres
Comment trier une liste de SelectItems
Sortie du livre "Introduction à Java"
[Swift] Comment obtenir le nombre d'éléments dans un tableau (super basique)
Essayez d'ajouter du texte à une image avec Scala en utilisant la bibliothèque standard de Java
Comment créer une petite image docker de l'application openjdk 11 (EA) (1 Go → 85 Mo)
Créez vos propres raccourcis avec Xcode pour éliminer les travaux d'installation compliqués des pods
Comment définir des variables d'environnement dans le fichier de propriétés de l'application Spring Boot
[Order method] Définit l'ordre des données dans Rails
Comment trouver la cause de l'erreur Ruby
Bouton [Rails] pour revenir en haut de la page
Personnalisez la répartition du contenu de Recyclerview
Faire une marge à gauche du TextField
Je veux var_dump le contenu de l'intention
Comment obtenir le jour d'aujourd'hui
Changer le fuseau horaire du conteneur https-portal en JST
[Ruby] Code pour afficher le jour
[Java] (pour MacOS) Méthode de définition du chemin de classe
Créer une application en spécifiant la version de Rails
Rails6.0 ~ Comment créer un environnement de développement respectueux de l'environnement
[Java / Kotlin] Redimensionner en tenant compte de l'orientation de l'image
L'histoire de l'ajout du dernier Node.js à DockerFile
J'ai essayé de configurer tomcat pour exécuter le servlet.
Comment afficher le résultat du remplissage du formulaire
Modifier le dossier de placement de l'image et du conteneur Docker
Poussez l'image vers le hub docker à l'aide de Jib
Comment créer un certificat OLEORE (certificat SSL, auto-certificat)
Java Bienvenue dans le marais des tableaux bidimensionnels
[Développement Android] Obtenez des images du serveur avec Java et définissez-les dans ImageView! !!