Lock/Unlock bits emulation

May 26, 2015 at 1:52 PM
Hello

I need to iterate through the all pixels of the image and make some actions with each pixel.
For example:
BitmapData data = image.LockBits();

int stride = data.Stride;
int bpp = data.BitsPerPixel / 8;
byte* scan0 = (byte*)data.Scan0.ToPointer();

for (int y = 0; y < image.Height; y++)
{
    for (int x = 0; x < image.Width; x++)
    {
        // some actions
        pos += bpp;
    }
}
image.UnlockBits(data);
But looks like Lock/Unlock bits functionality has not implemented yet for Magick.NET.

Can anyone provide me an example how I can get a pointer to the buffer that contains the bitmap data in memory(IntPtr) to work on with it?
Coordinator
May 26, 2015 at 2:06 PM
You are looking for the GetWritablePixels method of MagickImage. You will get a copy of the buffer in memory and not a pointer to the actual data. You might also want to took a look at the Evaluate method to modify the pixels.
May 27, 2015 at 5:47 AM
dlemstra wrote:
You are looking for the GetWritablePixels method of MagickImage. You will get a copy of the buffer in memory and not a pointer to the actual data. You might also want to took a look at the Evaluate method to modify the pixels.
Hello Dirk

hm.. how can I save changed data to the actual buffer in a memory?
There is any way how I can change actual data without copying it to the buffer and back(I need maximum performance)?
Coordinator
May 27, 2015 at 6:25 AM
You cannot directly access the memory of an image. You should use the Write method of the WritablePixelCollection to save the pixels. Would you mind explaining why you need access to those pixels? There might be a method in Magick.NET that can already do what you need to do.
May 27, 2015 at 7:04 AM
I don't think so that copying data to the WritablePixelCollection, change it and then copying back - can provide maximum performance in my case.
It would be great If I will be able to change data directly in a memory(like LockBits method do).

Maybe there is a way to get a pointer to the buffer using C++ ?
Coordinator
May 27, 2015 at 7:22 AM
Would you mind answering my question and tell me why do you need access to the pixel buffer? What are you doing with those pixels? This is starting to feel like premature optimization. Copying memory from one buffer to another buffer is probably the least of your worries.
May 27, 2015 at 7:33 AM
dlemstra wrote:
Would you mind answering my question and tell me why do you need access to the pixel buffer? What are you doing with those pixels?
sure I can:
for example I need to extract the alpha component of every pixel; calculate average brightness for pixels in the bitmap and so on.
May 27, 2015 at 7:37 AM
Dirk
regarding WritablePixelCollection: how I can determine Stride and BitsPerPixel properties?
Coordinator
May 27, 2015 at 4:07 PM
Edited May 27, 2015 at 4:13 PM
There is no stride in ImageMagick and the BitsPerPixel depends on if you are using the Q8 or the Q16 version of Magick.NET The Q8 version is 8bits per channel and Q16 is 16bits per channel. And with the Channels property you can get the number of channels that the image contains. If you multiply them you can get the BitsPerPixel.

You might want to take a look at the FormatExpression method. You can find help about that here: http://www.imagemagick.org/script/escape.php. With some fx: calculation (http://www.imagemagick.org/script/fx.php) you can probably get the values that you want.
May 29, 2015 at 11:06 AM
Edited May 29, 2015 at 11:19 AM
Dirk,
thanks for your help!

One more question: how can I determine PixelFormat for image?
Coordinator
May 29, 2015 at 3:07 PM
There is no such thing as PixelFormat in ImageMagick/Magick.NET. The pixels can be stored 'indexed' (with a color map) or with 8/16 bits per channel.
Jun 2, 2015 at 6:29 AM
Thanks.

I have some more questions. Could you help me?
  1. How can I convert 8-bit per channel ARGB(32bppArgb) image to 8-bit indexed(8bppIndexed) image ?
  2. There is any way to update Image DPI without resampling it? MagickImage.Resample updates DPI but it also changes image size.
Jun 2, 2015 at 8:20 AM
Edited Jun 2, 2015 at 8:21 AM
3.There is any way to get palette for image?
Jun 4, 2015 at 12:46 PM
k0ral wrote:
Thanks.

I have some more questions. Could you help me?
  1. How can I convert 8-bit per channel ARGB(32bppArgb) image to 8-bit indexed(8bppIndexed) image ?
  2. There is any way to update Image DPI without resampling it? MagickImage.Resample updates DPI but it also changes image size.
Regarding my second question: I figured out that I can use ImageMagick.Density property for this purpose.
Coordinator
Jun 5, 2015 at 5:14 PM
  1. You can change the image to indexed by setting the ColorType to Palette or PaletteAlpha.
  2. You can get information about the palette with ColorMapSize and ColorMap.
Jun 8, 2015 at 11:33 AM
Dirk, I appreciate your help.