Added new class Color III

This commit is contained in:
Robert Vokac 2024-10-01 17:13:34 +02:00
parent 1e8721fbaf
commit b1c3ff2d28
Signed by: robertvokac
GPG Key ID: FB9CE8E20AADA55F
5 changed files with 296 additions and 31 deletions

View File

@ -19,6 +19,12 @@
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.graphics;
import com.pixelgamelibrary.api.PixelException;
import static com.pixelgamelibrary.api.graphics.ColorDepth.BITS_16;
import static com.pixelgamelibrary.api.graphics.ColorDepth.BITS_24;
import static com.pixelgamelibrary.api.graphics.ColorDepth.BITS_32;
import static com.pixelgamelibrary.api.graphics.ColorDepth.BITS_4;
import static com.pixelgamelibrary.api.graphics.ColorDepth.BITS_8;
import lombok.Data;
/**
@ -79,6 +85,15 @@ public final class Color {
float iFloat = i;
return iFloat / BITS_IN_ONE_BYTE;
}
// Counts distance between two colors
public static double colorDistance(Color c1, Color c2) {
float rDiff = c2.getRed() - c1.getRed();
float gDiff = c2.getGreen() - c1.getGreen();
float bDiff = c2.getBlue() - c1.getBlue();
return Math.sqrt(rDiff * rDiff + gDiff * gDiff + bDiff * bDiff);
}
// Default alpha value for colors
public static final float DEFAULT_ALPHA = 1f;
@ -192,6 +207,10 @@ public final class Color {
intElementToFloat(alpha));
}
public double distanceTo(Color anotherColor) {
return colorDistance(this, anotherColor);
}
/**
* Blends this color with the specified color by multiplying their
* respective components.
@ -407,74 +426,148 @@ public final class Color {
return floatElementToInt(alpha);
}
/**
* Converts the color components to 16-bit representation. The red and blue
* components are each reduced to 5 bits, while the green component is
* reduced to 6 bits. The conversion is done by shifting the integer values
* right to discard the lower bits. This method modifies the existing color
* instance.
*/
public void set16Bit() {
this.red = floatElementToInt(this.red) >> 3; // 5 bitů
this.green = floatElementToInt(this.green) >> 2; // 6 bitů
this.blue = floatElementToInt(this.blue) >> 3; // 5 bitů
this.red = floatElementToInt(this.red) >> 3; // 5 bits for red
this.green = floatElementToInt(this.green) >> 2; // 6 bits for green
this.blue = floatElementToInt(this.blue) >> 3; // 5 bits for blue
}
/**
* Converts the color components to 8-bit representation. All color
* components are shifted to utilize the maximum possible values within the
* limits of 3 bits for red and green (maximum value of 7) and 2 bits for
* blue (maximum value of 3). This method modifies the existing color
* instance.
*/
public void set8Bit() {
this.red = floatElementToInt(this.red) >> 5; // 3 bity (max 7)
this.green = floatElementToInt(this.green) >> 5; // 3 bity (max 7)
this.blue = floatElementToInt(this.blue) >> 6; // 2 bity (max 3)
this.red = floatElementToInt(this.red) >> 5; // 3 bits for red (max 7)
this.green = floatElementToInt(this.green) >> 5; // 3 bits for green (max 7)
this.blue = floatElementToInt(this.blue) >> 6; // 2 bits for blue (max 3)
}
/**
* Converts the color components to 4-bit representation. Each color
* component is reduced to 2 bits, allowing for values from 0 to 3. This is
* achieved by shifting the integer values right to discard the lower bits.
* This method modifies the existing color instance.
*/
public void set4Bit() {
this.red = floatElementToInt(this.red) >> 1; // 2 bitů
this.green = floatElementToInt(this.green) >> 1; // 2 bitů
this.blue = floatElementToInt(this.blue) >> 1; // 2 bitů
this.red = floatElementToInt(this.red) >> 1; // 2 bits for red
this.green = floatElementToInt(this.green) >> 1; // 2 bits for green
this.blue = floatElementToInt(this.blue) >> 1; // 2 bits for blue
}
public void setWhiteBlack8Bit() {
int grayscale = (int) ((red + green + blue) / 3 * 255);
this.red = this.green = this.blue = grayscale / 255f; // Černobílý
this.red = this.green = this.blue = grayscale / 255f;
}
public void setWhiteBlack4Bit() {
int grayscale = (int) ((red + green + blue) / 3 * 15);
this.red = this.green = this.blue = grayscale / 15f; // Černobílý
this.red = this.green = this.blue = grayscale / 15f;
}
public void setWhiteBlack2Bit() {
int grayscale = (int) ((red + green + blue) / 3 * 3);
this.red = this.green = this.blue = grayscale / 3f; // Černobílý
this.red = this.green = this.blue = grayscale / 3f;
}
public void setWhiteBlack1Bit() {
int grayscale = (int) ((red + green + blue) / 3 * 1);
this.red = this.green = this.blue = grayscale / 1f; // Černobílý
this.red = this.green = this.blue = grayscale / 1f;
}
public int getByteRepresentation16Bit() {
return (floatElementToInt(this.red) << 11) | (floatElementToInt(this.green) << 5) | floatElementToInt(this.blue);
public void setWithBitCount(int bitCount) {
ColorDepth colorDepth = ColorDepth.from(bitCount);
switch (colorDepth) {
case BITS_32:
return;
case BITS_24:
return;
case BITS_16:
set16Bit();
break;
case BITS_8:
set8Bit();
break;
case BITS_4:
set4Bit();
break;
default:
throw new PixelException("Unsupported color depth: " + bitCount);
}
}
public int getByteRepresentation8Bit() {
return (floatElementToInt(this.red) << 4) | (floatElementToInt(this.green) << 2) | floatElementToInt(this.blue);
public void setWhiteBlackWithBitCount(int bitCount) {
switch (bitCount) {
case 8:
setWhiteBlack8Bit();
break;
case 4:
setWhiteBlack4Bit();
break;
case 2:
setWhiteBlack2Bit();
break;
case 1:
setWhiteBlack1Bit();
break;
default:
throw new PixelException("Unsupported bit count: " + bitCount);
}
}
public int getByteRepresentation4Bit() {
return (floatElementToInt(this.red) << 2) | (floatElementToInt(this.green) << 1) | floatElementToInt(this.blue);
public void set(ColorMode colorMode, int bitCount) {
if (colorMode == ColorMode.COLOR) {
setWithBitCount(bitCount);
return;
}
if (colorMode == ColorMode.BLACK_AND_WHITE) {
setWhiteBlackWithBitCount(bitCount);
return;
}
throw new PixelException("Unsupported ColorMode: " + colorMode);
}
public int getByteRepresentationWhiteBlack8Bit() {
int grayscale = (int) ((red + green + blue) / 3 * 255);
return grayscale;
public byte[] getByteRepresentation32Bit() {
return null;//todo
}
public int getByteRepresentationWhiteBlack4Bit() {
int grayscale = (int) ((red + green + blue) / 3 * 15);
return grayscale;
public byte[] getByteRepresentation24Bit() {
return null;//todo
}
public int getByteRepresentationWhiteBlack2Bit() {
int grayscale = (int) ((red + green + blue) / 3 * 3);
return grayscale;
public byte[] getByteRepresentation16Bit() {
return null;//todo
}
public int getByteRepresentationWhiteBlack1Bit() {
int grayscale = (int) ((red + green + blue) / 3 * 1);
return grayscale;
public byte[] getByteRepresentation8Bit() {
return null;//todo
}
public byte[] getByteRepresentation4Bit() {
return null;//todo
}
public byte[] getByteRepresentation2Bit() {
return null;//todo
}
public byte[] getByteRepresentation1Bit() {
return null;//todo
}
public byte[] getByteRepresentation(ColorMode colorMode, int bitCount) {
return null;//todo
}
@Override

View File

@ -0,0 +1,83 @@
package com.pixelgamelibrary.api.graphics;
///////////////////////////////////////////////////////////////////////////////////////////////
// Pixel: Game library.
// Copyright (C) 2024 the original author or authors.
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////package com.pixelgamelibrary.api.graphics;
/**
*
* @author robertvokac
*/
public class Color4BitPalette {
private Color4BitPalette() {
//Not meant to be instantiated.
}
public static final Color BLACK = new Color(0, 0, 0);
public static final Color BLUE = new Color(0, 0, 255);
public static final Color GREEN = new Color(0, 255, 0);
public static final Color CYAN = new Color(0, 255, 255);
public static final Color RED = new Color(255, 0, 0);
public static final Color MAGENTA = new Color(255, 0, 255);
public static final Color YELLOW = new Color(255, 255, 0);
public static final Color WHITE = new Color(255, 255, 255);
public static final Color GRAY = new Color(128, 128, 128);
public static final Color DARK_BLUE = new Color(0, 0, 128);
public static final Color DARK_GREEN = new Color(0, 128, 0);
public static final Color DARK_CYAN = new Color(0, 128, 128);
public static final Color DARK_RED = new Color(128, 0, 0);
public static final Color DARK_MAGENTA = new Color(128, 0, 128);
public static final Color DARK_YELLOW = new Color(128, 128, 0);
public static final Color LIGHT_GRAY = new Color(192, 192, 192);
// Define a color palette for 4-bit graphics (16 colors)
private static final Color[] COLORS_4BIT_PALETTE = {
Color4BitPalette.BLACK,
Color4BitPalette.BLUE,
Color4BitPalette.GREEN,
Color4BitPalette.CYAN,
Color4BitPalette.RED,
Color4BitPalette.MAGENTA,
Color4BitPalette.YELLOW,
Color4BitPalette.WHITE,
Color4BitPalette.GRAY,
Color4BitPalette.DARK_BLUE,
Color4BitPalette.DARK_GREEN,
Color4BitPalette.DARK_CYAN,
Color4BitPalette.DARK_RED,
Color4BitPalette.DARK_MAGENTA,
Color4BitPalette.DARK_YELLOW,
Color4BitPalette.LIGHT_GRAY
};
public static Color findClosestColor(Color color) {
Color closestColor = null;
double minDistance = Double.MAX_VALUE;
for (Color paletteColor : COLORS_4BIT_PALETTE) {
double distance = paletteColor.distanceTo(color);
if (distance < minDistance) {
minDistance = distance;
closestColor = paletteColor;
}
}
return closestColor;
}
}

View File

@ -0,0 +1,58 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// Pixel: Game library.
// Copyright (C) 2024 the original author or authors.
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.graphics;
import com.pixelgamelibrary.api.PixelException;
import lombok.Getter;
/**
*
* @author robertvokac
*/
public enum ColorDepth {
BITS_32(32),
BITS_24(24),
BITS_16(16),
BITS_8(8),
BITS_4(4);
@Getter
private final int bitCount;
ColorDepth(int bitCount) {
this.bitCount = bitCount;
}
public static ColorDepth from(int bitCount) {
switch (bitCount) {
case 32:
return BITS_32;
case 24:
return BITS_24;
case 16:
return BITS_16;
case 8:
return BITS_8;
case 4:
return BITS_4;
default:
throw new PixelException("Unsupported bit depth");
}
}
}

View File

@ -0,0 +1,29 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// Pixel: Game library.
// Copyright (C) 2024 the original author or authors.
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.graphics;
/**
*
* @author robertvokac
*/
public enum ColorMode {
COLOR,
BLACK_AND_WHITE;
}

View File

@ -27,4 +27,6 @@ package com.pixelgamelibrary.api.graphics;
public interface Texture {
void makeColorTransparent(int r, int g, int b);
void scale(double d);
void setColorMode(ColorMode colorMode, int bitCount);
}