[JAVA] Traitement d'image: jouons avec l'image

introduction

La dernière fois, j'ai regardé comment le programme enregistre l'image et l'affiche avec le code réel. Cette fois, faisons en fait diverses images basées sur cela (?).

Préparation préalable

** Image utilisée cette fois ** image.png

** Code JAVA de base **

ImageProcessing02.java


package ImageProcessing;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ImageProcessing02 {
	public static void main(String[] args) {
		BufferedImage original = null;
		try {
			original = ImageIO.read(new File("image.png ")); //Apportez l'image à modifier
		} catch (IOException e) {
			e.printStackTrace();
		}
		int iWidth = original.getWidth();				//Largeur de l'image
		int iHeight = original.getHeight();				//Largeur verticale de l'image
		int[] iColor = new int[iWidth * iHeight];		//Créez un tableau qui enregistre les informations de couleur en fonction de la largeur et de la hauteur
		int[] iChangeColor = new int[iWidth * iHeight]; //Un tableau pour stocker des données modifiées de même taille
		
		//Créez une variable BufferedImage à modifier à l'avance.
		BufferedImage img = new BufferedImage(iWidth, iHeight, BufferedImage.TYPE_4BYTE_ABGR);
		
		//Apportez des informations de couleur d'image avec getRGB
		original.getRGB(0, 0, iWidth, iHeight, iColor, 0, iWidth);
		
		/**********************
		 *Écrivez le code ici.*
		 **********************/

		//Définissez les informations de couleur modifiées dans l'image tamponnée pour modification
		img.setRGB(0, 0, iWidth, iHeight, iChangeColor, 0, iWidth);
		
		try {
			ImageIO.write(img, "png", new File("Route du fichier image à enregistrer")); //Enregistrer l'image
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Il y a des cas où l'instruction de déclaration au milieu est modifiée, mais les bases sont comme ça.

Rotation d'image

Cette fois, nous ne tournerons pas librement à 360 °, mais uniquement à angle droit (90 °). (Parce qu'une fonction triangulaire est absolument nécessaire pour la faire tourner librement)

** * Ne laissez un commentaire que là où il a changé **

ImageProcessing02_1.java


package ImageProcessing;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ImageProcessing02_1 {
	public static void main(String[] args) {
		BufferedImage original = null;
		try {
			original = ImageIO.read(new File("image.png "));
		} catch (IOException e) {
			e.printStackTrace();
		}
		int iWidth = original.getWidth();
		int iHeight = original.getHeight();
		int[] iColor = new int[iWidth * iHeight];
		int[] iChangeColor = new int[iWidth * iHeight];
		
		original.getRGB(0, 0, iWidth, iHeight, iColor, 0, iWidth);

		//Puisque la largeur et la hauteur changent en fonction de la situation, déclarez-la simplement
		BufferedImage img = null;
		
		/**Image Rotate(Rotate 90)**/
		int iRotate = 90;                                                      //Réglez l'angle de braquage
		int iRotateS = iRotate / 90;
		int iChangeWidth = 0, iChangeHeight = 0;

		//Paramètres de largeur et de hauteur(0, 180,360 degrés= 0 / 90,270 degrés= 1)
		switch(iRotateS % 2) {
		case 0:
			iChangeWidth = iWidth;
			iChangeHeight = iHeight;
			break;
		case 1:
			iChangeWidth = iHeight;
			iChangeHeight = iWidth;
			break;
		}
		img = new BufferedImage(iChangeWidth, iChangeHeight, BufferedImage.TYPE_4BYTE_ABGR);
		int iTargetRow = 0, iTargetCol = 0;
		for(int i = 0; i < iChangeHeight; i++) {
			for(int j = 0; j < iChangeWidth; j++) {
				//Vérifiez le reste pour qu'il puisse gérer 360 ° ou plus
				switch(iRotateS % 4) {
				case 0: //Tel quel
					iTargetRow = i;
					iTargetCol = j;
					break;
				case 1: //90 °, du bas à gauche vers le haut de l'image
					iTargetRow = iChangeWidth - (j + 1);
					iTargetCol = i;
					break;
				case 2: //180 °, de bas à droite à gauche de l'image
					iTargetRow = iChangeHeight - (i + 1);
					iTargetCol = iChangeWidth - (j + 1);
					break;
				case 3: //270 °, du haut à droite vers le bas de l'image
					iTargetRow = j;
					iTargetCol = iChangeHeight - (i + 1);
					break;
				}
				
				int iTargetIndex = (iTargetRow * iWidth) + iTargetCol;
				int iChangeIndex = (i * iChangeWidth) + j;
				iChangeColor[iChangeIndex] = iColor[iTargetIndex]; 
			}
		}

		img.setRGB(0, 0, iWidth, iHeight, iChangeColor, 0, iWidth);
		
		try {
			ImageIO.write(img, "png", new File("ImageRotate.png "));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

La formule d'indexation des coordonnées est la même que dans l'article précédent. La chose la plus importante dans cet article est le calcul des coordonnées. Il est important de savoir quelle couleur de l'image originale est placée. Dans le cas d'une rotation à angle droit, il est important de partir d'où et dans quelle direction lire. Voyons l'image réelle.

** Image originale ** image.png

** Rotation à 90 ° ** ImageRotate.png

L'image d'origine et l'image ont pivoté de 90 °. L'important ici est la provenance de la 0ème couleur de l'image. À 90 °, les couleurs du bas à droite vers le haut à droite sont alignées en ligne droite.

Les autres angles sont les mêmes, mais en déterminant les coordonnées de couleur lorsque l'angle change de cette manière, C'est OK si vous le mettez selon les coordonnées à changer.

Inversion d'image

ImageProcessing02_2.java


package ImageProcessing;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ImageProcessing02_2 {
	public static void main(String[] args) {
		BufferedImage original = null;
		try {
			original = ImageIO.read(new File("image.png "));
		} catch (IOException e) {
			e.printStackTrace();
		}
		int iWidth = original.getWidth();		
		int iHeight = original.getHeight();		
		int[] iColor = new int[iWidth * iHeight];	
		int[] iChangeColor = new int[iWidth * iHeight]; 
		
		BufferedImage img = new BufferedImage(iWidth, iHeight, BufferedImage.TYPE_4BYTE_ABGR);
		original.getRGB(0, 0, iWidth, iHeight, iColor, 0, iWidth);
		
		boolean isVerticalChange = true; //retourner à l'envers
		boolean isHorizonChange = true; //Retourner horizontalement
		for(int i = 0; i < iHeight; i++) {
			for(int j = 0; j < iWidth; j++) {
				int iChangeRow = (isVerticalChange) ? iHeight - ( i + 1 ) : i; //À l'envers de bas en haut
				int iChangeCol = (isHorizonChange) ? iWidth - ( j + 1 ) : j;  //Inversion gauche-droite de l'extrême droite vers la gauche
				int iChangeIndex = (iChangeRow * iWidth) + iChangeCol;
				
				int iTargetIndex = (i * iWidth) + j;
				
				iChangeColor[iChangeIndex] = iColor[iTargetIndex];
			}
		}
		img.setRGB(0, 0, iWidth, iHeight, iChangeColor, 0, iWidth);
		
		try {
			ImageIO.write(img, "png", new File("ImageReverse.png "));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

C'est presque le même qu'avant. Vérifiez s'il est retourné verticalement ou horizontalement avec Boolean et modifiez les coordonnées en conséquence. Si les deux sont réglés sur vrai, la rotation à 180 ° et le fonctionnement sont identiques.

Découpez une partie de l'image

ImageProcessing02_3.java


package ImageProcessing;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ImageProcessing02_3 {
	public static void main(String[] args) {
		BufferedImage original = null;
		try {
			original = ImageIO.read(new File("image.png "));
		} catch (IOException e) {
			e.printStackTrace();
		}
		int iWidth = original.getWidth();		
		int iHeight = original.getHeight();		
		int[] iColor = new int[iWidth * iHeight];	
		original.getRGB(0, 0, iWidth, iHeight, iColor, 0, iWidth);
		
		//Coordonnées pour commencer la coupe
		int iChangeY = 50;
		int iChangeX = 50;
		//Taille de coupe
		int iChangeWidth = 100;
		int iChangeHeight = 100;

		//Déclarez un tableau et une variable BufferedImage en fonction de la taille à couper.
		int[] iChangeColor = new int[iChangeWidth * iChangeHeight]; 
		BufferedImage img = new BufferedImage(iChangeWidth, iChangeHeight, BufferedImage.TYPE_4BYTE_ABGR);

		//Boucle basée sur la taille à couper
		for(int i = 0; i < iChangeHeight; i++) {
			for(int j = 0; j < iChangeWidth; j++) {
				//Déterminez les coordonnées des informations de couleur à partir des coordonnées où vous commencez la découpe.
				int iTargetRow = iChangeY + i;
				int iTargetCol = iChangeX + j;
				int iTargetIndex = (iTargetRow * iWidth) + iTargetCol;
				
				int iChangeIndex = (i * iChangeWidth) + j;
				
				iChangeColor[iChangeIndex] = iColor[iTargetIndex];
			}
		}

		img.setRGB(0, 0, iWidth, iHeight, iChangeColor, 0, iWidth);
		
		try {
			ImageIO.write(img, "png", new File("ImageSlice.png "));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Si vous souhaitez couper une partie de l'image, commencez par le coin supérieur gauche de l'endroit où vous souhaitez couper les coordonnées de départ Ce n'est pas grave si vous mélangez la taille à découper. Cependant, si cela reste tel quel, la boucle peut dépasser la taille de l'image, veuillez donc essayer de la corriger.

Divisez comme un puzzle

ImageProcessing02_4.java


package ImageProcessing;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ImageProcessing02_4 {
	public static void main(String[] args) {
		BufferedImage original = null;
		try {
			original = ImageIO.read(new File("image.png "));
		} catch (IOException e) {
			e.printStackTrace();
		}
		int iWidth = original.getWidth();		
		int iHeight = original.getHeight();		
		int[] iColor = new int[iWidth * iHeight];	
		original.getRGB(0, 0, iWidth, iHeight, iColor, 0, iWidth);

		int iPieceW = 3; //Nombre de pièces horizontales
		int iPieceH = 4; //Nombre de pièces verticales

		//Réglage de la taille en fonction du nombre de pièces
		int iChangeWidth = iWidth / iPieceW;
		int iChangeHeight = iHeight / iPieceH;

		//Déclarez un tableau pour les informations de couleur sous forme de tableau bidimensionnel basé sur la taille et le nombre de pièces
		int[][] iChangeColor = new int[iPieceW * iPieceH][iChangeWidth * iChangeHeight];

		//BufferedImage est également déclaré comme un tableau
		BufferedImage[] img = new BufferedImage[iPieceW * iPieceH];
		for(int i = 0; i < img.length; i++) {
			img[i] = new BufferedImage(iChangeWidth, iChangeHeight, BufferedImage.TYPE_4BYTE_ABGR);
		}

		for(int i = 0; i < iHeight; i++) {
			int iNowY = i / iChangeHeight; //Quelle ligne est la pièce
			if(iNowY >= iPieceH) break;     //Quitter quand il y a un repos et que le nombre de coordonnées dépasse le nombre défini
			for(int j = 0; j < iWidth; j++) {
				int iNowX = j / iChangeWidth; //Combien de rangées sont les pièces
				if(iNowX >= iPieceW) continue;     //Ignorer quand il y a un repos et que le nombre de coordonnées dépasse le nombre défini

				int iChangeRow = i % iChangeHeight;
				int iChangeCol = j % iChangeWidth;
				
				int iTargetIndex = (i * iWidth) + j;
				int iChangeIndex = (iChangeRow * iChangeWidth) + iChangeCol;
				int iChangeKey = iNowY * iPieceW + iNowX;
				
				iChangeColor[iChangeKey][iChangeIndex] = iColor[iTargetIndex];
			}
		}

		img.setRGB(0, 0, iWidth, iHeight, iChangeColor, 0, iWidth);
		
		try {
			for(int i = 0; i < img.length; i++) {
				ImageIO.write(img[i], "png", new File("ImageSlice" + String.format("%03d", i) + ".png "));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

C'est un code qui divise l'image uniformément comme un puzzle d'image. Déclarez BufferedImage en tant que tableau, divisez à nouveau les coordonnées et faites correspondre la taille à diviser Ce serait facile si nous pouvions changer la clé.

Édition d'image à l'aide de getGraphics ()

ImageProcessing02_5.java


package ImageProcessing;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ImageProcessing02_5 {
	public static void main(String[] args) {
		BufferedImage original = null;
		try {
			original = ImageIO.read(new File("image.png "));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//Apportez les graphismes de l'image
		Graphics g = original.getGraphics();
		
		//Dessinez des cercles de différentes couleurs sur l'image.
		g.setColor(Color.RED);
		g.fillOval(70, 70, 100, 100);
		g.setColor(Color.GREEN);
		g.fillOval(20, 120, 100, 100);
		g.setColor(Color.BLUE);
		g.fillOval(70, 170, 100, 100);
		g.setColor(Color.BLACK);
		g.fillOval(120, 120, 100, 100);
		
		try {
			ImageIO.write(original, "png", new File("ImageEdit.png "));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

résultat ImageEdit.png

Utilisation de la bibliothèque graphique prise en charge par JAVA Code qui modifie une image à l'aide d'une méthode de la bibliothèque. Vous n'avez pas à penser au code RVB ou aux coordonnées si dur.

Cependant, il n'a pas de fonctions de traitement d'image compliquées. Les graphiques seuls ne suffisent pas. Ainsi, comme la méthode précédente, de nombreuses fonctions peuvent être créées simplement en changeant le code RVB et les coordonnées. Veuillez essayer de le faire directement.

À la fin

Cette fois, c'est le plus difficile à comprendre que j'ai écrit dans l'article précédent, J'ai introduit des codes qui utilisent l'indexation des coordonnées du code RVB, mais comment était-ce? C'est l'une des bases du traitement d'image, mais les bases sont les plus importantes. Maîtrisons-le bien et entrons dans le monde du traitement d'image!

Recommended Posts

Traitement d'image: jouons avec l'image
Vérifions le filtre de recherche d'images
Oui, prévisualisons l'image. ~ part5 ~
Faisons une carte de Noël avec Processing!
[Swift5] Arrondissez l'image acquise avec UIImagePicker
Vérifiez le contenu du traitement avec [rails] binding.pry
Implémentez le système de box ball avec Processing
Noël avec traitement
[LeJOS] Contrôlons le moteur EV3 avec Java
Utilisez la barre de menus Mac avec les applications Processing 3
Jouons avec Minishift! Expérience facile de kubernetes
Traitement d'image: structure de base de l'image lue par le programme
Comprenons la fonction!
Faisons le traitement du cryptage!
Transparence de l'image d'arrière-plan (superposition de l'image avec votre couleur préférée)
[LeJOS] Contrôlons à distance le moteur EV3 avec Java
Contrôlez le flux de traitement Spring Batch avec JavaConfig.
J'ai essayé d'augmenter la vitesse de traitement avec l'ingénierie spirituelle
Créez une image Docker avec le JDK Oracle installé (miam
Saisissons l'image de fonctionnement (atmosphère) du conteneur DI de Spring
[Java] [Play Framework] Jusqu'à ce que le projet soit démarré avec Gradle
Réécrire les affectations de langage C de l'université avec Node.js
Premiers pas avec le traitement Doma-Annotation
Jouez avec le client Jersey OAuth 2
Expérimentons l'expansion en ligne Java
Java pour jouer avec Function
Améliorons l'application
Changer de port avec SpringBoot
[Form_with] Unifions le formulaire avec form_with.
Exploitons Excel avec Java! !!
Le jeu d'instancier java.lang.Void
Spring avec Kotorin --6 Traitement asynchrone
Comprenons la déclaration if!
Essayons le tutoriel S2Struts (# 3_180425)
Essayons le tutoriel S2Struts (# 5_180526)
Essayons le tutoriel S2Struts (# 4_180505)
Résolvons le problème FizzBuzz!
Comprenons la déclaration for-in!
Essayons le tutoriel S2Struts (# 2_180424)
Diapositive de présentation réalisée avec Processing
Avec l'erreur Cordova-> Looper.prepare ()
Image JavaFX-Load en arrière-plan
J'ai essayé d'implémenter la fonction de prévisualisation d'image avec Rails / jQuery
Jouez avec le logiciel de simulation classique NGS wgsim ~ Mysterious creature Pooh ~