-3

Hi there I have a greyscale jpeg image and I need to open it and convert it in rgb. I need the fastest way is possible but I've not been able to find one. For me it's fine to populate the rgb values with the greyscale value. Just doing using setpixel and getpixel takes a while. I'm wondering if there is a fastest way I ignore.

On the web there are a lot of solution to convert rgb to greyscale but it's very hard to find the opposite.

I've tried using FormatConvertedBitmap but I just get error I don't know how to use it correctly. If that is the solution please can anybody write me the code to load the greyscale image from a jpeg file and then create the rgb bitmap?

Thanks in advance!!!

davide93
  • 1
  • 5
  • 1
    The fastest way to do image manipulation would be working with the byte data instead of the embedded SetPixel methods. If you want to get a colored image back out of it, then exact results are not really possible. There are many combinations that can lead to a single grayscale image. If you just want an image with pixel data for all three colors and you accept the gray value then it should be very easy. Have a look here: https://stackoverflow.com/a/2016509/4871566 – DeveloperExceptionError Aug 06 '18 at 08:38
  • As far as I know there is no way to infer original color values once the image has been saved in grayscale. – fredrik Aug 06 '18 at 08:43
  • You can create a rgb image of the same size and drawimage the greyscale bitmap onto it. Or use lockbits to fill in the data.. – TaW Aug 06 '18 at 08:45
  • This question is extremely unclear, so you just want a Bitmap that was saved as greyscale as 24bit or 32bit pixel format? – TheGeneral Aug 06 '18 at 09:04
  • My image is 8bit. One only channel 0-255.And I need a greyscale image just with the three channels R=G=B. I hope now I've cleared every doubt. – davide93 Aug 06 '18 at 10:46
  • I'm now checking the solution suggested at this link:stackoverflow.com/a/2016509/4871566 – DeveloperExceptionError – davide93 Aug 06 '18 at 10:47

3 Answers3

1

There are some things in this question that aren't explicitly specified, so I'm gonna make some assumptions here.

The first assumption i'm making is that the input grayscale image doesn't have a 3 byte RGB value to determine the color of a pixel, instead I assume that for each pixel in the grayscale image, there is only 1 byte specifying what tint it represents in the grayscale.

This, where 0 represents black and 255 represents white.

Because a RGB value for each pixel has 1 byte for the color red, 1 byte for the color green and 1 byte for the color blue (3 bytes total), there is no way of converting the mentioned grayscale image into a RGB image, because there is not enough data for this.

What you could do though, is use the grayscale image tint per pixel, and set this value for all three RGB values. You would still end up with a grayscale image though, but in a different pixel format (RGB).

EDIT: I wrote some code after doing some research about how to solve this, it requires a file C:\image\image1.bmp:

   //load input image (bitmap)
    Bitmap image1 = new Bitmap(@"C:\image\image1.bmp");

    //create output image (bitmap) and set the new pixel format
    Bitmap image2 = new Bitmap(image1.Width, image1.Height,
        System.Drawing.Imaging.PixelFormat.Format24bppRgb);

    //draw the input image on the output image within a specified rectangle (area)
    using (Graphics gr = Graphics.FromImage(image2)) {
        gr.DrawImage(image1, new Rectangle(0, 0, image2.Width, image2.Height));
    }

    //save output image
    image2.Save(@"C:\image\image2.bmp");
Lennart
  • 763
  • 1
  • 5
  • 18
  • A greyscale image, unless things has changed since when I studied image processing, if not specified is intended exactly as you did 8 bit 1 single channel with value from 0 to 255. So since you guessed it correctly I don't see why this question is unclear at your eyes. Your suggestion is what I wanted to avoid. I need something faster than that. What you are suggesting is to replicate pixel per pixel the three RGB values. In c++ I would simply assign the array values to the three channels but here I know only setpixel and getpixel to do it and that is really slow. thank you! – davide93 Aug 10 '18 at 07:10
0

Anyway my final solution was to add a compression quality setting like explained in the post: High quality JPEG compression with c# I will post it here below maybe someone can find it useful:

ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);
System.Drawing.Imaging.Encoder myEncoder =  System.Drawing.Imaging.Encoder.Quality;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 100L);
myEncoderParameters.Param[0] = myEncoderParameter;

Bitmap orig = new Bitmap(@imageor); // imageor is the complete path of the original image

Bitmap clone = new Bitmap(orig.Width, orig.Height,
System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
using (Graphics gr = Graphics.FromImage(clone))
{
     gr.DrawImage(orig, new Rectangle(0, 0, clone.Width, clone.Height));
}
clone.Save(clonergb, jpgEncoder, myEncoderParameters); // clonergb is the complete path of the cloned jpeg RGB image
davide93
  • 1
  • 5
-2

the solution proposed at the link: stackoverflow.com/a/2016509/4871566 – DeveloperExceptionError worked very well. Thanks to the guy who posted it!!!!!! This is my solution:

Bitmap orig = new Bitmap(@imagenamecm);
                //imagenamecm is the link to the 8bit-greyscale image
                Bitmap clone = new Bitmap(orig.Width, orig.Height,
                    System.Drawing.Imaging.PixelFormat.Format32bppPArgb);

                using (Graphics gr = Graphics.FromImage(clone))
                {
                    gr.DrawImage(orig, new Rectangle(0, 0, clone.Width, clone.Height));
                }
                    clone.Save(imagenamecmrgb, System.Drawing.Imaging.ImageFormat.Jpeg);
                //  imagenamecmrgb is the path for the greyscale rgb image
davide93
  • 1
  • 5
  • Please can I ask why this has -2? That was the solution for me. I would be glad if a moderator could jump in here. – davide93 Aug 07 '18 at 22:33
  • I'm not really surprised; you're taking the credit for something posted in a comment. Also, if this solved your problem, then it also means the question is a duplicate; the given question has the exact same problem, namely, "how to convert between pixel formats?" That said, people should really post such things as answers themselves rather than as comments. – Nyerguds Aug 08 '18 at 18:41
  • I think there is a huge misunderstanding here. – davide93 Aug 09 '18 at 20:34
  • Please read what I've written just before the code. I didn't post it to get credits but just to thanks the guy who suggested me the link. I'm not very expert in programming and neither in stackoverflow communication. I'm sorry if I've offended someone in posting the solution that by the way I had to further change it because that was destroying my image due to the jpeg compression. – davide93 Aug 09 '18 at 20:43
  • I didn't downvote anything. I'm just answering your question. – Nyerguds Aug 09 '18 at 21:39
  • I didn't say you downvoted my post. I just wanted to point out I had explained it was not my code. For this reason I was wondering why someone wanted to downvote it. I wasn't expect any vote actually. For this reason I would have loved any stackoverflow moderator could have jumped in. I'm not here to steal credit to anybody. I really love this service and if my questions can help any other not expert like me I will be fine with that. – davide93 Aug 10 '18 at 07:06