Can I create an Int24 (24-bit type) in C #?

The main task:

  1. Fill every single white area on a binary image with a unique color Format24bppRgb color++ ( color++ for each next area).
  2. Get a complete list of such objects, consisting of a finite set of pixels.
  • five
    And what's stopping you from using 24 bits out of 32 and not doing a separate type? - Vladimir Martyanov
  • 2
    Well, you can create something, get a structure of three byte . But why? I would simply use an array of bytes corresponding to the memory fill, and write procedures that read / write the value at the index. (By the way, do not forget about stride.) - VladD
  • I would like to edit Bitmaps with one assignment in 24bppRgb format, and not with separate RGB byte components that do not carry a semantic load for this task. - Artyom Ionash
  • @DukeSpontaneous: Well, it probably makes sense. But if you start an array of such Int24 , are you going to copy it into memory of the image byte-by-byte? (Because, due to the alignment, you most likely will not be able to blit it). Believe my experience will be slow. (However, try it.) - VladD
  • @VladD: No, now I am simply laying out the image in the uint matrix via Buffer.BlockCopy to work with it in 2D coordinates. But theoretically, I wonder how it, for example, can be decomposed into a matrix of 24 bits from BitmapData.Scan0 . - Artyom Ionash

3 answers 3

You have approached the task from the wrong side. You, apparently, are trying to make a 24-bit data type to arrange it in an array that will repeat the image in structure. But in C #, this is difficult to do.

Instead, you can make a separate class with an indexer that will look like an array from the outside - and inside it will itself correctly distribute the pixel colors by bytes:

 public class BitmapAccessor { private byte[] scan0; // Или любое другое хранилище private int stride; // (3 * width + 3) / 4 * 4. Ну или можно взять это число из BitmapData.Stride // ... public Color this[int x, int y] { get { var index = 3 * x + stride * y; return Color.FromArgb(scan0[index], scan0[index+1], scan0[index+2]); // точный формат не помню, возможно аргументы надо поменять местами } set { var index = 3 * x + stride * y; scan0[index] = value.R; scan0[index+1] = value.G; scan0[index+2] = value.B; } } } 

    It is not necessary to build a bike. Take the ready-made System.Drawing.Bitmap class, it allows you to work with pixels as you like, including choosing the depth from 4 to 48 bits, the format you specified, and a few more specific formats. More details in the documentation .

    Filling, however, will have to implement independently, there is no finished one. But you can take advantage of vector capabilities if you feed the Bitmap into the Graphics constructor.

    You can work with color using the System.Drawing.Color class and the FromArgb() and ToArgb , which enable you to get and set the color with the usual int . Details in the documentation here , here and here .

    • I decided to work in the format Format32bppRgb for now. But I was wondering if there are any convenient means for working with the 24-bit format, which is very popular: after all, in the absence of types of the appropriate size, it is much more difficult to even convert the read image into a matrix. Or do you offer to read by pixel through the class? - Artyom Ionash
    • @DukeSpontaneous And how do you plan to make a fill without referring to individual pixels? maybe I just don't know what, but it seems like the only option for the raster. - rdorn
    • @ rdorn: yes, I do this by referring to individual pixels, but not by invoking the GetPixel() class's GetPixel() method, but by working with a copy decomposed into a uint 'new matrix. - Artyom Ionash
    • @DukeSpontaneous Well, if you really need high performance, then, as far as I understand, in an unsafe block, you can simply get a pointer to the image matrix and work with it directly. Although I have not done this yet. - rdorn
    • @DukeSpontaneous from the use of methods performance sags? It seems to me that if you’ve been wise with creating a separate structure for 24bpp, it won’t get much better, anyway, there will be overhead costs, you have to measure this already - rdorn
    1. Use only 24 bits of the 32-bit number.

    2. Create a separate structure with three bytes or a separate class with an array of 3 bytes.

    • 3
      Better structure to match Int32 behavior. - VladD
    • @VladD I agree, you can and structure. - Max ZS
    • one
      @VladD In general, in my opinion, this question is raised with enviable periodicity. And surely the answer to it would not be difficult to find. - Max ZS
    • Well, then it was probably worth closing as a duplicate? - VladD