Cynnie Jia Ответов: 1

Измените цвет картинки, но только наполовину


Повторно вставьте полный код:
private void Adjust(Bitmap pBitmap, params int[] pValues)
        {
Prepare(pValues);
            BitmapData pBitmapData = pBitmap.LockBits(
                new Rectangle(0, 0, pBitmap.Width, pBitmap.Height),
                ImageLockMode.ReadWrite,
                PixelFormat.Format24bppRgb);

            byte[] pData = new byte[pBitmapData.Stride * pBitmapData.Height];
            Marshal.Copy(pBitmapData.Scan0, pData, 0, pData.Length);

            int iOffset = pBitmapData.Stride - pBitmapData.Width * 3;
            int iIndex = 0;

            for (int i = 0; i < pBitmapData.Height; i++)
            {
                for (int j = 0; j < pBitmapData.Width; j++)
                {
                    for (int k = iIndex; k < iIndex + 3; k++)
                    {
                        pData[k] = Adjust(pData[k], k);
                    }
                    iIndex += 3;
                }
                iIndex += iOffset;
            }

            Marshal.Copy(pData, 0, pBitmapData.Scan0, pData.Length);
}

protected void Prepare(int[] pValues)
        {
            m_iRed = pValues[0];
            m_iGreen = pValues[1];
            m_iBlue = pValues[2];
        }

 protected byte Adjust(byte iValue, int iIndex)
        {
            int nColour = 0;

            switch (iIndex % 3)
            {
                case 0:
                    nColour = (int)iValue + m_iBlue;
                    break;
                case 1:
                    nColour = (int)iValue + m_iGreen;
                    break;
                case 2:
                    nColour = (int)iValue + m_iRed;
                    break;
            }

          
            return Fix(nColour);
        }
  protected byte Fix(int iValue)
        {
            if (iValue < 0) iValue = 0;
            if (iValue > 255) iValue = 255;
            return (byte)iValue;
        }


Что я уже пробовал:

у меня картина разделена на четыре части.я хочу изменить цвет на RGB,но изменил только половину.
1. изменение не удалось, когда ширина изображения меньше 256.
2.my маленькая картинка максимум не более 256.
3.Каждая картинка 256*256-это нормально.
4. параметр задачи:r=0,g=0, b=52.


Извините, я не знаю, как ответить внизу.

о решении Ральфа Мейера
При смене пиксельного цикла я отлаживаю цвет картинки и не меняю картинку, они имеют одинаковое значение.

о решении Йохена Арндта
В то время код не вставлялся полностью,для расчета значения я был отремонтирован Fix.
Изменено на абсолютное значение, по-прежнему никакого эффекта.
На данный момент я все еще не нашел проблему.

изображение не меняет цвет при установке r=0, g=0, b=52: https://i.stack.imgur.com/IIrgd.jpg

Ralf Meier

Вы должны проверить свою K-петлю.
Я бы сказал, что вы пытаетесь получить доступ с помощью k+1, k+2 и k+3 к индексу вне вашего изображения, Если i или j заканчиваются ...

Jochen Arndt

Редактируя ваши вопросы несколько раз, ответы могут вырваться из контекста. При редактировании вы должны указать новый раздел и объяснить, что было изменено.

Если вы хотите ответить на решения и комментарии, используйте соответствующие опции ("есть вопрос или комментарий"). При этом отправляются уведомления по электронной почте. На этот раз я увидел, что вы отредактировали свой вопрос, адресованный мне. Но на это нельзя полагаться.

"Изменено на абсолютное значение, все еще никакого эффекта."
Что происходит с неправильным индексом, переданным функции Adjust ()?
Хотя это не исправлено, результат всегда неверен и затрудняет поиск других ошибок.

1 Ответов

Рейтинг:
8

Jochen Arndt

Обратите внимание, что Растровые данные.Собственность Шага (Системы.Рисование.Изображений)[^] будет отрицательным с восходящими растровыми изображениями. Поэтому вы должны использовать абсолютное значение:

int iStride = Math.Abs(pBitmapData.Stride);
byte[] pData = new byte[iStride * pBitmapData.Height];
int iOffset = iStride - pBitmapData.Width * 3;


Другая проблема заключается в использовании байтового индекса в вашем Adjust функция для определения того, является ли байт значением R, G или B. Хотя это будет работать для первой строки, это не относится к другим из-за шага (начальный индекс строки всегда кратен четырем, что может не давать нулевого модуля). Таким образом, вы не должны передавать индекс, но k - iIndex (или перепишите свой код).

Я не знаю, являются ли вышеприведенные данные источником видимой проблемы (изменилась только половина цветов), но они приведут к неправильным преобразованиям.

[РЕДАКТИРОВАТЬ]
Может быть и третья проблема:
Вы настраиваете цвета, добавляя значение без проверки на переполнение. С вашим m_iBlue значение 52, каждое синее значение больше 203 будет становиться меньше. Если это не предназначено, вы должны проверить наличие переполнений и установить результат равным 255:
protected byte Adjust(byte iValue, int iIndex)
{
    // ...
    return nColour > 255 ? 255 : nColour;
}

[/РЕДАКТИРОВАТЬ]