[JAVA] Bearbeiten Sie Pixel, um ein Bild eines Mandelbrot-Sets zu erstellen

Einführung

Um Pixel in der Bildverarbeitung zu manipulieren, habe ich ein Bild eines Mandelbrot-Sets erstellt (Details siehe Wikipedia). Java gibt Ihnen das Gesamtbild und C # und C ++ geben Ihnen ein Bild des entsprechend vergrößerten Teils. Grundsätzlich scheint es schneller zu sein, direkt in das interne Array zu schreiben, als eine Methode wie "image.setPixel (i, j, color)" zu verwenden.

Java Während C # und C ++ für jeden Kanal angeordnet sind, ist Java ein Element, das ARGB zu einer 32-Bit-Ganzzahl kombiniert.

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 Parameter einstellen
    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;
     
    //Punkt(i, j)Berechnen Sie die Farbe für 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);
		}
	}
}

Ergebnis: mandelbrot1.png

Referenz: Bildpixel mit Java bearbeiten | Naberogu -2q-4XSAhWKgrwKHYoDAugQFggaMAA & url = http% 3A% 2F% 2Fblog.nabe-ch.net% 2F% 3Fp% 3D532 & usg = AFQjCNHl-RIE4VzT1sbyfrpzRNMPOLTUeA & sig2 = ckR-ckR-ckR-ckL-ckR-ckR-ckR-ckL

C# Es scheint, dass es in C # keine Konvertierung zwischen HSV und RGB gibt, also Wikipedia Ich habe es mit Bezug auf gemacht.

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 Parameter einstellen
        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;
        
        //Punkt(i, j)Berechnen Sie die Farbe für 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));
            }
        }
        
        //Konvertieren Sie von ARGB zu 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;
            }
        }
    }
}

Ergebnis: mandelbrot2.png

Referenz: [[C #] So greifen Sie pixelweise mit hoher Geschwindigkeit auf Bitmap zu (GetPixel / SetPixel vs. BitmapData-Geschwindigkeitsvergleich)](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++ Ich habe OpenCV verwendet. Dieses Mal ist alles undurchsichtig, daher macht es keinen Sinn, aber es scheint, dass OpenCV nicht zwischen HSV und RGB konvertieren kann, wenn Alpha-Werte enthalten sind (c ++ --OpenCV cv :: cvtColor löscht Alpha-Kanal, Wie werden Alpha-Daten gespeichert?).

#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 Parameter einstellen
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;

//Punkt(i, j)Berechnen Sie die Farbe für HSV
//Der Bereich von h reicht von 0 bis 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)));
	}
}

Ergebnis: mandelbrot3.png

Referenz: ・ OpenCV 2 lernen

Recommended Posts

Bearbeiten Sie Pixel, um ein Bild eines Mandelbrot-Sets zu erstellen
Einfache Möglichkeit, eine Implementierung von java.util.stream.Stream zu erstellen
Stellen Sie die Zeit von LocalDateTime auf eine bestimmte Zeit ein
So stellen Sie das Bild mithilfe der Symbolschriftart (Symbole) links / rechts von der Schaltfläche auf zeichnbar ein
So beurteilen Sie den Klick eines beliebigen Bildbereichs
[Schienen] So zeigen Sie Bilder in der Ansicht an
[Swift5] So erhalten Sie ein Array und eine Reihe von Unterschieden zwischen Arrays
So legen Sie die IP-Adresse und den Hostnamen von CentOS8 fest
Korrigieren Sie den Namen der Kriegsdatei auf den in Maven festgelegten
Die Geschichte von toString () beginnt mit der Übergabe eines Arrays an System.out.println
[Android Studio] Legen Sie ein beliebiges Bild für den Anwendungshintergrund fest. [Java]
Die in /lib/calendars.properties von Java jre festgelegte Millisekunde ist UTC
So ermitteln Sie die Länge einer Audiodatei mit Java
So machen Sie den Einzug zu zwei Einzelbyte-Leerzeichen in der JAXB-Implementierung des JDK
So konvertieren Sie ein Array von Strings mit der Stream-API in ein Array von Objekten
Rufen Sie den Typ eines Elements eines Arrays ab, um festzustellen, ob es sich um ein Array handelt
Ändern Sie das Speicherziel des Bildes in der Rails-App in S3. Teil 2
So beschneiden Sie ein Bild in libGDX
Zeigen Sie Text über dem Bild an
So verwischen Sie das Bild (super einfach)
Vergleichen Sie Elemente eines Arrays (Java)
[Java] So stellen Sie die Datums- und Uhrzeit auf 00:00:00 ein
Konvertieren Sie ein Array von Zeichenfolgen in Zahlen
So sortieren Sie eine Liste von SelectItems
Ausgabe des Buches "Einführung in Java"
[Swift] So ermitteln Sie die Anzahl der Elemente in einem Array (Super Basic)
Versuchen Sie, mit Scala mithilfe der Standardbibliothek von Java Text zu einem Bild hinzuzufügen
So erstellen Sie ein kleines Docker-Image der openjdk 11 (ea) -Anwendung (1 GB → 85 MB)
Erstellen Sie mit Xcode Ihre eigenen Verknüpfungen, um komplizierte Pod-Installationsarbeiten zu vermeiden
So legen Sie Umgebungsvariablen in der Eigenschaftendatei der Spring-Boot-Anwendung fest
[Bestellmethode] Legen Sie die Reihenfolge der Daten in Rails fest
So finden Sie die Ursache des Ruby-Fehlers
Schaltfläche [Schienen], um zum Anfang der Seite zurückzukehren
Passen Sie an, wie der Inhalt von Recyclerview aufgeteilt wird
Machen Sie einen Rand links vom TextField
Ich möchte den Inhalt der Absicht var_dump
Wie komme ich zum heutigen Tag?
Ändern Sie die Zeitzone des https-Portal-Containers in JST
[Ruby] Code zur Anzeige des Tages
[Java] (für MacOS) Methode zur Einstellung des Klassenpfads
Erstellen Sie eine App, indem Sie die Rails-Version angeben
Rails6.0 ~ So erstellen Sie eine umweltfreundliche Entwicklungsumgebung
[Java / Kotlin] Ändern Sie die Größe unter Berücksichtigung der Ausrichtung des Bildes
Die Geschichte des Hinzufügens der neuesten Node.js zu DockerFile
Ich habe versucht, Tomcat so einzustellen, dass das Servlet ausgeführt wird.
So zeigen Sie das Ergebnis des Ausfüllens des Formulars an
Ändern Sie den Docker-Image- und Container-Platzierungsordner
Schieben Sie das Image mit Jib zum Docker-Hub
So erstellen Sie ein Oleore-Zertifikat (SSL-Zertifikat, Selbstzertifikat)
Java Willkommen im Sumpf der zweidimensionalen Arrays
[Android-Entwicklung] Holen Sie sich mit Java Bilder vom Server und legen Sie sie in ImageView fest! !!