2025.09.07

RGBをHSVに変換する その1

RGBをHSVに変換するソースコードについて

ここでは、色を表現するRGBの値をHSVに変換するJavaソースコードについて詳しく説明します。ソースコードの概要は以下の通りです。

色相H、彩度S、明度Vを計算するメソッドを作成

色相H、彩度S、明度Vを計算するメソッドをそれぞれ作成します。引数RGBの3つの値で、それぞれ0.0~1.0の範囲で渡します。

RGBの値をキーボードで入力

RGBの値をそれぞれキーボードで入力します。値の範囲は0~255です。

このソースコードでは、入力した値のチェックは行いません。数字以外の値や、0~255の範囲外の値を入力した場合、エラーまたは正しくない計算結果が出力されます。

HSVの値を計算

①で作成したメソッドに、②で入力した値を255.0で割った値を引数として渡して、色相H、彩度S、明度Vの値を計算します。

HSVの計算結果を出力

計算した色相H、彩度S、明度Vの値をprintlnメソッドコンソール出力します。

Javaソースコード

キーボードで入力したRGBの値でHSVを計算するJavaソースコードです。

RGBtoHSV.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import java.util.Scanner;

public class RGBtoHSV {
	// 0.0に近い値を定義(値は任意)
	final static double E = 0.0000000000000000001;

	// RGBの値から色相Hを求めるメソッド(RGBの範囲チェックはしません)
	//  rとgとbの範囲は0.0~1.0
	//  戻り値の範囲は0.0~360.0
	private static double rgb2h( double r, double g, double b )
	{
		// RGBの最小値cmin、最大値cmaxを求める
		double cmin = Math.min( r, Math.min( g, b ) );
		double cmax = Math.max( r, Math.max( g, b ) );

		// 色相hの計算
		double h;

		if ( E > Math.abs( cmin - cmax ) )
			h = 0.0;	// RGBの値が全て同じ
		else {
			if ( E > Math.abs( r - cmax ) )
				h = 60.0 * ( g - b ) / ( cmax - cmin );	// Rが最大値の場合
			else {
				if ( E > Math.abs( g - cmax ) )
					h = 60.0 * ( b - r ) / ( cmax - cmin ) + 120.0;	// Gが最大値の場合
				else
					h = 60.0 * ( r - g ) / ( cmax - cmin ) + 240.0;	// Bが最大値の場合
			}
		}

		// 計算したhがマイナスの場合、360を足してプラスにする
		if ( 0.0 > h ) h += 360.0;

		// 計算した色相hを戻す
		return h;
	}


	// RGBの値から彩度Sを求めるメソッド(RGBの範囲チェックはしません)
	//  rとgとbの範囲は0.0~1.0
	//  戻り値の範囲は0.0~1.0
	private static double rgb2s( double r, double g, double b )
	{
		// RGBの最小値cmin、最大値cmaxを求める
		double cmin = Math.min( r, Math.min( g, b ) );
		double cmax = Math.max( r, Math.max( g, b ) );

		// 彩度sを計算
		double s; 

		if ( E > Math.abs( cmax ) )
			s = 0.0;	// cmaxが0.0の場合
		else
			s = ( cmax - cmin ) / cmax;

		// 計算した彩度sを戻す
		return s;
	}


	// RGBの値から明度Vを求めるメソッド(RGBの範囲チェックはしません)
	//  rとgとbの範囲は0.0~1.0
	//  戻り値の範囲は0.0~1.0
	private static double rgb2v( double r, double g, double b )
	{
		// RGBの最大値cmaxを求める
		double cmax = Math.max( r, Math.max( g, b ) );

		// 明度vを計算
		double v = cmax;

		// 計算した明度vを戻す
		return v;
	}


	// メインメソッド
	public static void main( String[] args ) {
		// Scannerを作成
		Scanner scan = new Scanner( System.in );

		// Rの値を入力
		System.out.println( "Rの値をを入力してください(0-255)" );
		int r = scan.nextInt();

		// Gの値を入力
		System.out.println( "Gの値をを入力してください(0-255)" );
		int g = scan.nextInt();

		// Bの値を入力
		System.out.println( "Bの値をを入力してください(0-255)" );
		int b = scan.nextInt();


		// rgbの値を0.0~1.0に変換
		double rd =  (double)r / 255.0;
		double gd =  (double)g / 255.0;
		double bd =  (double)b / 255.0;

		// 色相Hの計算
		double h = rgb2h( rd, gd, bd );

		// 彩度Sの計算
		double s = rgb2s( rd, gd, bd );

		// 明度Vの計算
		double v = rgb2v( rd, gd, bd );


		// 結果を出力
		System.out.println( "R : " + r );
		System.out.println( "G : " + g );
		System.out.println( "B : " + b );

		System.out.println();

		System.out.println( "色相H : " + h );
		System.out.println( "彩度S : " + s );
		System.out.println( "明度V : " + v );
	}
}

実行結果

コンパイル ソースコードが「ANSI」の場合

C:\talavax\javasample>javac -encoding sjis RGBtoHSV.java

コンパイル ソースコードが「UTF-8」の場合

C:\talavax\javasample>javac RGBtoHSV.java

実行

C:\talavax\javasample>java RGBtoHSV
Rの値をを入力してください(0-255)
255
Gの値をを入力してください(0-255)
0
Bの値をを入力してください(0-255)
0
R : 255
G : 0
B : 0

色相H : 0.0
彩度S : 1.0
明度V : 1.0

キーボードでR=255、G=0、B=0を入力して、HSVを計算した結果が出力されています。

Javaソースコードの解説

ここでは、Javaソースコードを上から順番に解説しています。

001
import java.util.Scanner;

Javaクラスライブラリの中から「java.util.Scanner」というパッケージにあるクラスを使うために記述しています。

003
public class RGBtoHSV {

クラス名を、RGBtoHSVとしています。

004
005
	// 0.0に近い値を定義(値は任意)
	final static double E = 0.0000000000000000001;

0.0に近い値をdouble型変数Eに代入しています。この値は任意で、double型の値が同じかを判定するのに使用します。

007
008
009
010
011
	// RGBの値から色相Hを求めるメソッド(RGBの範囲チェックはしません)
	//  rとgとbの範囲は0.0~1.0
	//  戻り値の範囲は0.0~360.0
	private static double rgb2h( double r, double g, double b )
	{

RGBの値から色相Hを求めるメソッドです。

引数r、g、bに0.0~1.0の値を渡します。戻り値の範囲は0.0~360.0です。

012
013
014
		// RGBの最小値cmin、最大値cmaxを求める
		double cmin = Math.min( r, Math.min( g, b ) );
		double cmax = Math.max( r, Math.max( g, b ) );

引数r、g、bの最小値をcminに、最大値をcmaxに代入しています。

Math.minメソッド

public static int Math.min( int a, int b )
public static long Math.min( long a, long b )
public static float Math.min( float a, float b )
public static double Math.min( double a, double b )
・2つの値のうち小さい方を返します。

  パラメータ a : 1つめの値
        b : 2つめの値

  戻り値     aとbのうち、小さい値

Math.maxメソッド

public static int Math.max( int a, int b )
public static long Math.max( long a, long b )
public static float Math.max( float a, float b )
public static double Math.max( double a, double b )
・2つの値のうち大きい方を返します。

  パラメータ a : 1つめの値
        b : 2つめの値

  戻り値     aとbのうち、大きい値
016
017
		// 色相hの計算
		double h;

色相の値を格納する変数hを宣言しています。

019
020
		if ( E > Math.abs( cmin - cmax ) )
			h = 0.0;	// RGBの値が全て同じ

cminとcmaxの値が同じ場合、色相hに0.0を代入しています。

cminとcmaxが同じかどうかは、cminとcmaxの差の絶対値が、0.0とみなす値を格納した変数Eより小さいという条件で判定しています。

RGBの値r、g、bの最小値cminと最大値cmaxが同じであれば、rとgとbの値は全て同じです。

Math.absメソッド

public static int Math.abs( int a )
public static long Math.abs( long a )
public static float Math.abs( float a )
public static double Math.abs( double a )
public static int Math.abs( byte a )
public static int Math.abs( short a )
・引数aに指定した数値の絶対値を返します。

  パラメータ a : 絶対値を求めたい数値

  戻り値     aの絶対値を返します。
  戻りの変数型は、基本的に引数と同じ変数型と考えてよいです。
021
022
023
		else {
			if ( E > Math.abs( r - cmax ) )
				h = 60.0 * ( g - b ) / ( cmax - cmin );	// Rが最大値の場合

rとcmaxの値が同じ場合、色相hの値を以下の式で計算しています。

	色相h = 60.0 * ( g - b ) / ( cmax - cmin )
024
025
026
			else {
				if ( E > Math.abs( g - cmax ) )
					h = 60.0 * ( b - r ) / ( cmax - cmin ) + 120.0;	// Gが最大値の場合

gとcmaxの値が同じ場合、色相hの値を以下の式で計算しています。

	色相h = 60.0 * ( b - r ) / ( cmax - cmin ) + 120.0
027
028
				else
					h = 60.0 * ( r - g ) / ( cmax - cmin ) + 240.0;	// Bが最大値の場合

bとcmaxの値が同じ場合、色相hの値を以下の式で計算しています。

	色相h = 60.0 * ( r - g ) / ( cmax - cmin ) + 240.0
032
033
		// 計算したhがマイナスの場合、360を足してプラスにする
		if ( 0.0 > h ) h += 360.0;

計算したhがマイナスの場合、360.0を足してプラスの値にしています。

035
036
		// 計算した色相hを戻す
		return h;

計算した色相hをreturnで戻しています。

040
041
042
043
044
	// RGBの値から彩度Sを求めるメソッド(RGBの範囲チェックはしません)
	//  rとgとbの範囲は0.0~1.0
	//  戻り値の範囲は0.0~1.0
	private static double rgb2s( double r, double g, double b )
	{

RGBの値から彩度Sを求めるメソッドです。

引数r、g、bに0.0~1.0の値を渡します。戻り値の範囲は0.0~1.0です。

045
046
047
		// RGBの最小値cmin、最大値cmaxを求める
		double cmin = Math.min( r, Math.min( g, b ) );
		double cmax = Math.max( r, Math.max( g, b ) );

引数r、g、bの最小値をcminに、最大値をcmaxに代入しています。

049
050
		// 彩度sを計算
		double s; 

彩度の値を格納する変数sを宣言しています。

052
053
054
055
		if ( E > Math.abs( cmax ) )
			s = 0.0;	// cmaxが0.0の場合
		else
			s = ( cmax - cmin ) / cmax;

cmaxが0.0の場合、変数sに0.0を代入しています。0.0でない場合以下の式で計算しています。

	彩度s = ( cmax - cmin ) ÷ cmax
057
058
		// 計算した彩度sを戻す
		return s;

計算した彩度sをreturnで戻しています。

062
063
064
065
066
	// RGBの値から明度Vを求めるメソッド(RGBの範囲チェックはしません)
	//  rとgとbの範囲は0.0~1.0
	//  戻り値の範囲は0.0~1.0
	private static double rgb2v( double r, double g, double b )
	{

RGBの値から明度Vを求めるメソッドです。

引数r、g、bに0.0~1.0の値を渡します。戻り値の範囲は0.0~1.0です。

067
068
		// RGBの最大値cmaxを求める
		double cmax = Math.max( r, Math.max( g, b ) );

引数r、g、bの最大値をcmaxに代入しています。

070
071
		// 明度vを計算
		double v = cmax;

明度の値を格納する変数vを宣言して、cmaxを代入しています。

073
074
		// 計算した明度vを戻す
		return v;

計算した明度vをreturnで戻しています。

078
079
	// メインメソッド
	public static void main( String[] args ) {

このmainメソッドからプログラムを実行します。

080
081
		// Scannerを作成
		Scanner scan = new Scanner( System.in );

標準入力System.inを使って、Scannerクラスの scanを初期化しています。

083
084
085
		// Rの値を入力
		System.out.println( "Rの値をを入力してください(0-255)" );
		int r = scan.nextInt();

nextIntメソッドで、キーボードから入力された1行を読み取り、その値をint型変数rに代入しています。

ここで、入力待ち状態になり、Enterキーが押されるまでに入力した値が変数rに格納されます。

キーボードの"Ctrl"キーを押しながら"C"を押すと強制終了します。

087
088
089
		// Gの値を入力
		System.out.println( "Gの値をを入力してください(0-255)" );
		int g = scan.nextInt();

nextIntメソッドで、キーボードから入力された1行を読み取り、その値をint型変数gに代入しています。

ここで、入力待ち状態になり、Enterキーが押されるまでに入力した値が変数gに格納されます。

キーボードの"Ctrl"キーを押しながら"C"を押すと強制終了します。

091
092
093
		// Bの値を入力
		System.out.println( "Bの値をを入力してください(0-255)" );
		int b = scan.nextInt();

nextIntメソッドで、キーボードから入力された1行を読み取り、その値をint型変数bに代入しています。

ここで、入力待ち状態になり、Enterキーが押されるまでに入力した値が変数bに格納されます。

キーボードの"Ctrl"キーを押しながら"C"を押すと強制終了します。

096
097
098
099
		// rgbの値を0.0~1.0に変換
		double rd =  (double)r / 255.0;
		double gd =  (double)g / 255.0;
		double bd =  (double)b / 255.0;

0~255で入力したr、g、bを255.0で割って、0.0~1.0に変換しています。

101
102
		// 色相Hの計算
		double h = rgb2h( rd, gd, bd );

rgb2hメソッドで計算した色相変数hに代入しています。

104
105
		// 彩度Sの計算
		double s = rgb2s( rd, gd, bd );

rgb2sメソッドで計算した彩度変数sに代入しています。

107
108
		// 明度Vの計算
		double v = rgb2v( rd, gd, bd );

rgb2vメソッドで計算した明度変数vに代入しています。

111
112
113
114
		// 結果を出力
		System.out.println( "R : " + r );
		System.out.println( "G : " + g );
		System.out.println( "B : " + b );

入力したRとGとBをprintlnメソッドコンソール出力しています。

116
		System.out.println();

改行しています。

118
119
120
		System.out.println( "色相H : " + h );
		System.out.println( "彩度S : " + s );
		System.out.println( "明度V : " + v );

計算結果の色相Hと、彩度S、明度Vをprintlnメソッドコンソール出力しています。

このソースコードでは、rgb2hメソッドとrgb2sメソッドの中でrgbの最小値cminと最大値cmaxを計算しています。また、rgb2vメソッドの中では最大値cmaxを計算しています。

HSVの値を同時に計算する場合は、各メソッドにあらかじめrgbから求めたcminとcmaxを引数で渡せば計算コストが下がります。

このソースコードでは、HSVの値を別々で計算できるように、引数をrgbだけにしています。

HSVに関するコンテンツ

HSV」に関係があるコンテンツをまとめています。

関連コンテンツ

条件式を判断して処理を分岐する方法を詳しく説明しています。

2023.03.20

メソッドを抜けるときに使用するreturn文について説明しています。

2020.03.20

変数やクラスに格納されている値をコンソール出力する方法は?

2020.03.23

プログラムの最初に実行されるメソッドは?

2022.12.13

プログラミングで使う変数って何?

2020.03.23

Javaのプログラムを書いてみませんか?プログラムの書き方をくわしく説明しています。

2020.03.23

「Javaソースコード」から実行可能な「オブジェクトコード」に変換する方法をくわしく説明しています。

2020.03.23

Javaのプログラムを作ってみませんか?プログラミングに必要なものの用意から実行までを説明しています。

2020.03.23

Javaプログラムを作るための環境構築の仕方を解説しています

2024.09.17

計算の仕方、変数の利用、繰り返し処理、分岐処理、文字列など、Javaプログラムの基本について説明しています

2020.03.23

Javaの学習に役立つソースコードを多数紹介しています。是非、ご覧ください。

2022.09.10

Swingパッケージを使ってグラフィック表示を行う方法を解説しています。

2020.03.23

画像フォーマット形式・色・大きさ・傾きなどの変更、特定の図形(文字・記号など)を見つけたり、取り出したりする画像処理について詳しく解説。

2015.11.29

繰り返し処理を使ったJavaのソースコードサンプルを紹介しています。

2020.03.23

配列を使うJavaソースコードを多数紹介しています。

2021.05.18

数学に関係するJavaのメソッドやソースコードなどを紹介しています。

2022.10.25

三角形、台形、円などいろいろな図形の面積を計算するプログラムを紹介しています。詳しくは、記事をご覧ください。

2021.05.18

StringクラスとStringBuilderクラスを利用したプログラミングの仕方を紹介しています。

2016.12.16

いろいろなJavaのソースコードで、日付と時間を取り扱う方法を解説します

2022.12.19

Javaを使った簡単な応用プログラム(生年月日から年齢を計算プログラムなど)を紹介しています。

2022.07.07

プログラミングに関係がある情報を紹介しています。色情報の考え方、文字コード、2進数、画像フォーマットなどについて解説しています

2023.05.27

プログラミング、ITに関する用語をまとめています。

2022.10.17

日本で使われてきた伝統文様「和柄」について解説しています。

2022.07.27

レベルごとに分けられた英単語と日本語の意味の一覧表、英語を見て日本語を当てるクイズ、日本語を見て英語を当てるクイズなどを掲載しています

2025.04.26

PCやスマートフォンのディスプレイに表示されている色、プリンターで印刷される色の仕組みについて解説しています。

2020.03.23

メソッドの定義方法を詳しく解説しています。Javaのサンプルソースコードを使った説明もあります。

2020.03.23

プログラミング言語とは?種類や特徴について説明しています。

2022.08.03

Javaプログラムの構成について解説しています。詳しくは、こちらをご覧ください。

2020.03.23

2つの値のうち、小さい方の値と、大きい方の値を取得する方法。

2020.03.23

絶対値の意味と、Math.absメソッドの使い方をソースコードを使って詳しく解説しています。

2020.03.23

プログラムとは?

2025.02.15

キーボードを使って整数値を入力する方法を解説しています。Scannerクラスを利用しています。

2023.03.08

文字列の途中で改行する方法って?詳しくは、記事を。

2021.02.02

「ゆるゆるプログラム」のコンテンツを紹介しています。興味のある方はこの記事をご覧ください。

2020.03.23

広告