如何将灰度效果应用于位图图像

How to apply the grayscale effect to the Bitmap image?

本文关键字:应用于 位图 图像 灰度      更新时间:2023-10-16

我想将位图图像转换为灰度。为此,我正在使用NDK来提高应用程序的性能。我已经成功地应用了其他效果。

问题::

我用来应用灰度的代码取自C#。所以,我想把它转换成NDK。我不能做那部分。。

作为参考,我把我如何应用青色效果的代码图像。

下面粘贴的代码运行良好。

void applyCyano(Bitmap* bitmap) {
    //Cache to local variables
    unsigned char* red = (*bitmap).red;
    unsigned char* green = (*bitmap).green;
    unsigned char* blue = (*bitmap).blue;
    unsigned int length = (*bitmap).width * (*bitmap).height;
    register unsigned int i;
    register unsigned char grey, r, g, b;
    for (i = length; i--;) {
        grey = ((red[i] * 0.222f) + (green[i] * 0.222f) + (blue[i] * 0.222f));
        r = componentCeiling(61.0f + grey);
        g = componentCeiling(87.0f + grey);
        b = componentCeiling(136.0f + grey);
        grey = blackAndWhite(red[i], green[i], blue[i]);
        red[i] = overlayPixelComponents(grey, r, 0.9f);
        green[i] = overlayPixelComponents(grey, g, 0.9f);
        blue[i] = overlayPixelComponents(grey, b, 0.9f);
    }
}

应用灰度效果的代码(取自网络上的C#示例)::

void applyGrayscaleNatively(Bitmap* original)
{
    //create an empty bitmap the same size as original
    Bitmap newBitmap = new Bitmap(original.Width, original.Height);
    //lock the original bitmap in memory
    BitmapData originalData = original.LockBits(
            new Rectangle(0, 0, original.Width, original.Height),
            ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
    //lock the new bitmap in memory
    BitmapData newData = newBitmap.LockBits(
            new Rectangle(0, 0, original.Width, original.Height),
            ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
    //set the number of bytes per pixel
    int pixelSize = 3;
    for (int y = 0; y < original.Height; y++)
    {
        //get the data from the original image
        byte* oRow = (byte*)originalData.Scan0 + (y * originalData.Stride);
        //get the data from the new image
        byte* nRow = (byte*)newData.Scan0 + (y * newData.Stride);
        for (int x = 0; x < original.Width; x++)
        {
            //create the grayscale version
            byte grayScale =
                    (byte)((oRow[x * pixelSize] * .11) + //B
                            (oRow[x * pixelSize + 1] * .59) +  //G
                            (oRow[x * pixelSize + 2] * .3)); //R
            //set the new image's pixel to the grayscale version
            nRow[x * pixelSize] = grayScale; //B
            nRow[x * pixelSize + 1] = grayScale; //G
            nRow[x * pixelSize + 2] = grayScale; //R
        }
    }
    //unlock the bitmaps
    newBitmap.UnlockBits(newData);
    original.UnlockBits(originalData);
}

我想做的事::

我从这里开始了这个项目,它为图像设置了不同的效果,但没有设置灰度。所以如何将灰度应用于代码,这样项目的所有其他功能都不会停止。

如果你需要我提供什么,请告诉我。

非常感谢。。

请帮助我解决这个问题,因为正因为如此,我无法在我的项目中走得更远。

使用以下函数将位图转换为Android中的灰度级,而不是转换C#版本的

public Bitmap toGrayscale(Bitmap bmpOriginal){        
int width, height;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();    
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bmpOriginal, 0, 0, paint);
return bmpGrayscale;
}

我解决了问题::

这是我的解决方案。。。

void applyGrayscaleNatively(Bitmap* bitmap)
{
    register unsigned int i;
    unsigned int length = (*bitmap).width * (*bitmap).height;
    register unsigned char grey;
    unsigned char* red = (*bitmap).red;
    unsigned char* green = (*bitmap).green;
    unsigned char* blue = (*bitmap).blue;
    float matrix[4][4];
    identMatrix(matrix);
    float saturation = 1.0f;
    saturateMatrix(matrix, &saturation);
    applyMatrix(bitmap, matrix);
    for (i = length; i--;) {
        float value;
        getBrightness(red[i], green[i], blue[i], &value);
        grey = grayScale(red[i], green[i], blue[i]);
        red[i] = grey;
        green[i] = grey;
        blue[i] = grey;
    }
}