#java #awt #hsb
#java #awt #hsb
Вопрос:
Я пытаюсь изменить насыщенность изображения на определенную величину, но получаю некоторые странные результаты. Я использую следующий код
// shiftAmount should be a float value between -1 and 1
public static int[] saturation( int[] pixels, float shiftAmount )
{
int[] newPixels = new int[ pixels.length ];
for( int i = 0; i < pixels.length; i )
{
// get HSB color values
Color rgb = new Color( pixels[ i ] );
float[] hsb = Color.RGBtoHSB( rgb.getRed(), rgb.getGreen(), rgb.getBlue(), null );
float hue = hsb[ 0 ];
float saturation = hsb[ 1 ];
float brightness = hsb[ 2 ];
// shift
saturation = shiftAmount;
if( saturation > 1f )
saturation = 1f;
else if( saturation < 0f )
saturation = 0f;
// convert HSB color back
newPixels[ i ] = Color.HSBtoRGB( hue, saturation, brightness );
}
return newPixels;
}
Ниже приведен пример 80%-ного сдвига насыщенности в другом программном обеспечении для редактирования изображений (Aseprite), в котором я сделал это с помощью собственного кода (используя 0.8f).
Как это выглядит, когда я использую Aseprite
Как это выглядит с использованием моего собственного кода
Как вы можете видеть, на последнем изображении цвета сильно искажены. Кто-нибудь знает, как это решить?
Комментарии:
1. Что произойдет, если вы «сдвинете» насыщенность, скажем, на 0,01? 0,8 кажется очень большим значением в диапазоне 0-1, особенно когда ваше базовое изображение с самого начала кажется очень насыщенным.
2. Когда я сдвигаюсь на небольшую величину, например, на 0,01, на самом деле ничего не происходит. Когда я начинаю увеличивать значение примерно до 3.0, искажение начинает становиться заметным.
3. Вы уверены, что значения пикселей, которые вы предоставляете, находятся в правильном формате для начала? Поскольку вы преобразуете целые числа в числа с плавающей запятой, а затем обратно в целые числа, возможно, что ваши входные данные могут быть полностью зашифрованы, и вы не заметите, пока не попытаетесь выполнить математическую обработку. Я считаю, что целочисленные входные данные должны иметь значения RGB в диапазоне 0-255, упакованные в определенном порядке в нижние 24 бита. Это то, что у вас есть?
4. Целочисленные значения являются шестнадцатеричными значениями. Например, 0xff_80bbc0. Я только что обнаружил проблему. Что Aseprite делал для вычисления новой насыщенности, так это
saturation = ( saturation * shiftAmount );
. Таким образом, например, белые цвета с низкой насыщенностью остаются низкими и белыми.