How to get new Bitmap from Byte Array with IntPtr pointer?
i have a problem with Marshal.UnsafeAddrOfPinnedArrayElement()
method.
What i want to do, is return Bitmap object
from byte
array. But first, some code below with explenation what i do.
First, i load my
Bitmap
to method that i returnbyte
array from it:
//return tuple with pointer to array and bytearray
public static (byte, IntPtr) GetByteArray(Bitmap bitmap)
{
//lockbits
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadWrite,
bitmap.PixelFormat
);
int pixels = bitmapData.Stride * bitmap.Height;
byte resultArray = new byte[pixels];
//copying bytes to array
Marshal.Copy(bitmapData.Scan0, resultArray, 0, pixels);
bitmap.UnlockBits(bitmapData);
//returns array and pointer to it
return (resultArray, bitmapData.Scan0);
}
Second, i want to edit that byte array:
public static Bitmap Execute(Bitmap bitmap, int filter)
{
//get byte array from method that i mentioned before with pointer to it
(byte pixelsFromBitmap, IntPtr pointer) = PictureUtilities.GetByteArray(bitmap);
byte newPixels = pixelsFromBitmap;
int stride = bitmap.Width;
int height = bitmap.Height;
int width = bitmap.Width;
Parallel.For(0, height - 1, y =>
{
int offset = y * stride;
for(int x = 0; x < width - 1; x++)
{
//some stuff i doing with array, not neceserry what im doing here
int positionOfPixel = x + offset;
newPixels[positionOfPixel] = (byte)122;
}
});
//copying values from newPixels to pixelsFromBitmap that i get from method GetByteArray() that i mentioned it before
newPixels.CopyTo(pixelsFromBitmap, 0);
//copying bytes again
Marshal.Copy(pixelsFromBitmap, 0, pointer, pixelsFromBitmap.Length);
//generete new bitmap from byte array
Bitmap result = new Bitmap(bitmap.Width, bitmap.Height, stride,
bitmap.PixelFormat,
pointer);
return result;
}
After all that process i get an Exception in Execute()
method: System.ArgumentException
in line, when i getting new Bitmap result
.
Could you tell me, what i doing wrong? i want to get a byte array from my bitmap from method (for readability), edit it and return new bitmap depends on my new byte array.
I bet, that i not clearly get, how Marshall.Copy
works and i get wrong pointer
to returning byte array
from GetByteArray()
method.
Thanks for help
c# arrays image interop marshalling
add a comment |
i have a problem with Marshal.UnsafeAddrOfPinnedArrayElement()
method.
What i want to do, is return Bitmap object
from byte
array. But first, some code below with explenation what i do.
First, i load my
Bitmap
to method that i returnbyte
array from it:
//return tuple with pointer to array and bytearray
public static (byte, IntPtr) GetByteArray(Bitmap bitmap)
{
//lockbits
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadWrite,
bitmap.PixelFormat
);
int pixels = bitmapData.Stride * bitmap.Height;
byte resultArray = new byte[pixels];
//copying bytes to array
Marshal.Copy(bitmapData.Scan0, resultArray, 0, pixels);
bitmap.UnlockBits(bitmapData);
//returns array and pointer to it
return (resultArray, bitmapData.Scan0);
}
Second, i want to edit that byte array:
public static Bitmap Execute(Bitmap bitmap, int filter)
{
//get byte array from method that i mentioned before with pointer to it
(byte pixelsFromBitmap, IntPtr pointer) = PictureUtilities.GetByteArray(bitmap);
byte newPixels = pixelsFromBitmap;
int stride = bitmap.Width;
int height = bitmap.Height;
int width = bitmap.Width;
Parallel.For(0, height - 1, y =>
{
int offset = y * stride;
for(int x = 0; x < width - 1; x++)
{
//some stuff i doing with array, not neceserry what im doing here
int positionOfPixel = x + offset;
newPixels[positionOfPixel] = (byte)122;
}
});
//copying values from newPixels to pixelsFromBitmap that i get from method GetByteArray() that i mentioned it before
newPixels.CopyTo(pixelsFromBitmap, 0);
//copying bytes again
Marshal.Copy(pixelsFromBitmap, 0, pointer, pixelsFromBitmap.Length);
//generete new bitmap from byte array
Bitmap result = new Bitmap(bitmap.Width, bitmap.Height, stride,
bitmap.PixelFormat,
pointer);
return result;
}
After all that process i get an Exception in Execute()
method: System.ArgumentException
in line, when i getting new Bitmap result
.
Could you tell me, what i doing wrong? i want to get a byte array from my bitmap from method (for readability), edit it and return new bitmap depends on my new byte array.
I bet, that i not clearly get, how Marshall.Copy
works and i get wrong pointer
to returning byte array
from GetByteArray()
method.
Thanks for help
c# arrays image interop marshalling
1
There are multiple problems with this code, you can't ignore the pixel format and cannot assume the stride is the same as the Width. The pixel data is only ever a byte if it uses 8bpp, that is very uncommon. Consider to get ahead by picking the fast-and-convenient pixel format, pass 32bppArgb to LockBits(). Now you can store and address the pixels with an int array and stride no longer matters.
– Hans Passant
Nov 13 '18 at 11:56
1
Thanks for correct my stride! But even if i correct that, it not answering my question why i get exception in that Bitmap constructor
– michasaucer
Nov 13 '18 at 12:05
1
The IntPtr becomes invalid as soon as you call UnlockBits(). Consider to get ahead by using LockBits and Marshal.Copy again, now copying the other way around. Or by not using an array at all and party on the int* directly, more efficient that way.
– Hans Passant
Nov 13 '18 at 13:02
1
Ok, i get it. So there is no efficient way to move byte array with pointer from another func? i need to do it in same method that i modify array? I used lock bits before, but i do all stuff (initializing byte from bitmap) in one method, now in refactor way i wanted to move that thing away
– michasaucer
Nov 13 '18 at 13:10
1
You have to throw away what you have and write version 2. You'll get there.
– Hans Passant
Nov 13 '18 at 13:13
add a comment |
i have a problem with Marshal.UnsafeAddrOfPinnedArrayElement()
method.
What i want to do, is return Bitmap object
from byte
array. But first, some code below with explenation what i do.
First, i load my
Bitmap
to method that i returnbyte
array from it:
//return tuple with pointer to array and bytearray
public static (byte, IntPtr) GetByteArray(Bitmap bitmap)
{
//lockbits
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadWrite,
bitmap.PixelFormat
);
int pixels = bitmapData.Stride * bitmap.Height;
byte resultArray = new byte[pixels];
//copying bytes to array
Marshal.Copy(bitmapData.Scan0, resultArray, 0, pixels);
bitmap.UnlockBits(bitmapData);
//returns array and pointer to it
return (resultArray, bitmapData.Scan0);
}
Second, i want to edit that byte array:
public static Bitmap Execute(Bitmap bitmap, int filter)
{
//get byte array from method that i mentioned before with pointer to it
(byte pixelsFromBitmap, IntPtr pointer) = PictureUtilities.GetByteArray(bitmap);
byte newPixels = pixelsFromBitmap;
int stride = bitmap.Width;
int height = bitmap.Height;
int width = bitmap.Width;
Parallel.For(0, height - 1, y =>
{
int offset = y * stride;
for(int x = 0; x < width - 1; x++)
{
//some stuff i doing with array, not neceserry what im doing here
int positionOfPixel = x + offset;
newPixels[positionOfPixel] = (byte)122;
}
});
//copying values from newPixels to pixelsFromBitmap that i get from method GetByteArray() that i mentioned it before
newPixels.CopyTo(pixelsFromBitmap, 0);
//copying bytes again
Marshal.Copy(pixelsFromBitmap, 0, pointer, pixelsFromBitmap.Length);
//generete new bitmap from byte array
Bitmap result = new Bitmap(bitmap.Width, bitmap.Height, stride,
bitmap.PixelFormat,
pointer);
return result;
}
After all that process i get an Exception in Execute()
method: System.ArgumentException
in line, when i getting new Bitmap result
.
Could you tell me, what i doing wrong? i want to get a byte array from my bitmap from method (for readability), edit it and return new bitmap depends on my new byte array.
I bet, that i not clearly get, how Marshall.Copy
works and i get wrong pointer
to returning byte array
from GetByteArray()
method.
Thanks for help
c# arrays image interop marshalling
i have a problem with Marshal.UnsafeAddrOfPinnedArrayElement()
method.
What i want to do, is return Bitmap object
from byte
array. But first, some code below with explenation what i do.
First, i load my
Bitmap
to method that i returnbyte
array from it:
//return tuple with pointer to array and bytearray
public static (byte, IntPtr) GetByteArray(Bitmap bitmap)
{
//lockbits
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadWrite,
bitmap.PixelFormat
);
int pixels = bitmapData.Stride * bitmap.Height;
byte resultArray = new byte[pixels];
//copying bytes to array
Marshal.Copy(bitmapData.Scan0, resultArray, 0, pixels);
bitmap.UnlockBits(bitmapData);
//returns array and pointer to it
return (resultArray, bitmapData.Scan0);
}
Second, i want to edit that byte array:
public static Bitmap Execute(Bitmap bitmap, int filter)
{
//get byte array from method that i mentioned before with pointer to it
(byte pixelsFromBitmap, IntPtr pointer) = PictureUtilities.GetByteArray(bitmap);
byte newPixels = pixelsFromBitmap;
int stride = bitmap.Width;
int height = bitmap.Height;
int width = bitmap.Width;
Parallel.For(0, height - 1, y =>
{
int offset = y * stride;
for(int x = 0; x < width - 1; x++)
{
//some stuff i doing with array, not neceserry what im doing here
int positionOfPixel = x + offset;
newPixels[positionOfPixel] = (byte)122;
}
});
//copying values from newPixels to pixelsFromBitmap that i get from method GetByteArray() that i mentioned it before
newPixels.CopyTo(pixelsFromBitmap, 0);
//copying bytes again
Marshal.Copy(pixelsFromBitmap, 0, pointer, pixelsFromBitmap.Length);
//generete new bitmap from byte array
Bitmap result = new Bitmap(bitmap.Width, bitmap.Height, stride,
bitmap.PixelFormat,
pointer);
return result;
}
After all that process i get an Exception in Execute()
method: System.ArgumentException
in line, when i getting new Bitmap result
.
Could you tell me, what i doing wrong? i want to get a byte array from my bitmap from method (for readability), edit it and return new bitmap depends on my new byte array.
I bet, that i not clearly get, how Marshall.Copy
works and i get wrong pointer
to returning byte array
from GetByteArray()
method.
Thanks for help
c# arrays image interop marshalling
c# arrays image interop marshalling
asked Nov 13 '18 at 9:41
michasaucermichasaucer
26516
26516
1
There are multiple problems with this code, you can't ignore the pixel format and cannot assume the stride is the same as the Width. The pixel data is only ever a byte if it uses 8bpp, that is very uncommon. Consider to get ahead by picking the fast-and-convenient pixel format, pass 32bppArgb to LockBits(). Now you can store and address the pixels with an int array and stride no longer matters.
– Hans Passant
Nov 13 '18 at 11:56
1
Thanks for correct my stride! But even if i correct that, it not answering my question why i get exception in that Bitmap constructor
– michasaucer
Nov 13 '18 at 12:05
1
The IntPtr becomes invalid as soon as you call UnlockBits(). Consider to get ahead by using LockBits and Marshal.Copy again, now copying the other way around. Or by not using an array at all and party on the int* directly, more efficient that way.
– Hans Passant
Nov 13 '18 at 13:02
1
Ok, i get it. So there is no efficient way to move byte array with pointer from another func? i need to do it in same method that i modify array? I used lock bits before, but i do all stuff (initializing byte from bitmap) in one method, now in refactor way i wanted to move that thing away
– michasaucer
Nov 13 '18 at 13:10
1
You have to throw away what you have and write version 2. You'll get there.
– Hans Passant
Nov 13 '18 at 13:13
add a comment |
1
There are multiple problems with this code, you can't ignore the pixel format and cannot assume the stride is the same as the Width. The pixel data is only ever a byte if it uses 8bpp, that is very uncommon. Consider to get ahead by picking the fast-and-convenient pixel format, pass 32bppArgb to LockBits(). Now you can store and address the pixels with an int array and stride no longer matters.
– Hans Passant
Nov 13 '18 at 11:56
1
Thanks for correct my stride! But even if i correct that, it not answering my question why i get exception in that Bitmap constructor
– michasaucer
Nov 13 '18 at 12:05
1
The IntPtr becomes invalid as soon as you call UnlockBits(). Consider to get ahead by using LockBits and Marshal.Copy again, now copying the other way around. Or by not using an array at all and party on the int* directly, more efficient that way.
– Hans Passant
Nov 13 '18 at 13:02
1
Ok, i get it. So there is no efficient way to move byte array with pointer from another func? i need to do it in same method that i modify array? I used lock bits before, but i do all stuff (initializing byte from bitmap) in one method, now in refactor way i wanted to move that thing away
– michasaucer
Nov 13 '18 at 13:10
1
You have to throw away what you have and write version 2. You'll get there.
– Hans Passant
Nov 13 '18 at 13:13
1
1
There are multiple problems with this code, you can't ignore the pixel format and cannot assume the stride is the same as the Width. The pixel data is only ever a byte if it uses 8bpp, that is very uncommon. Consider to get ahead by picking the fast-and-convenient pixel format, pass 32bppArgb to LockBits(). Now you can store and address the pixels with an int array and stride no longer matters.
– Hans Passant
Nov 13 '18 at 11:56
There are multiple problems with this code, you can't ignore the pixel format and cannot assume the stride is the same as the Width. The pixel data is only ever a byte if it uses 8bpp, that is very uncommon. Consider to get ahead by picking the fast-and-convenient pixel format, pass 32bppArgb to LockBits(). Now you can store and address the pixels with an int array and stride no longer matters.
– Hans Passant
Nov 13 '18 at 11:56
1
1
Thanks for correct my stride! But even if i correct that, it not answering my question why i get exception in that Bitmap constructor
– michasaucer
Nov 13 '18 at 12:05
Thanks for correct my stride! But even if i correct that, it not answering my question why i get exception in that Bitmap constructor
– michasaucer
Nov 13 '18 at 12:05
1
1
The IntPtr becomes invalid as soon as you call UnlockBits(). Consider to get ahead by using LockBits and Marshal.Copy again, now copying the other way around. Or by not using an array at all and party on the int* directly, more efficient that way.
– Hans Passant
Nov 13 '18 at 13:02
The IntPtr becomes invalid as soon as you call UnlockBits(). Consider to get ahead by using LockBits and Marshal.Copy again, now copying the other way around. Or by not using an array at all and party on the int* directly, more efficient that way.
– Hans Passant
Nov 13 '18 at 13:02
1
1
Ok, i get it. So there is no efficient way to move byte array with pointer from another func? i need to do it in same method that i modify array? I used lock bits before, but i do all stuff (initializing byte from bitmap) in one method, now in refactor way i wanted to move that thing away
– michasaucer
Nov 13 '18 at 13:10
Ok, i get it. So there is no efficient way to move byte array with pointer from another func? i need to do it in same method that i modify array? I used lock bits before, but i do all stuff (initializing byte from bitmap) in one method, now in refactor way i wanted to move that thing away
– michasaucer
Nov 13 '18 at 13:10
1
1
You have to throw away what you have and write version 2. You'll get there.
– Hans Passant
Nov 13 '18 at 13:13
You have to throw away what you have and write version 2. You'll get there.
– Hans Passant
Nov 13 '18 at 13:13
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53278011%2fhow-to-get-new-bitmap-from-byte-array-with-intptr-pointer%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53278011%2fhow-to-get-new-bitmap-from-byte-array-with-intptr-pointer%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
There are multiple problems with this code, you can't ignore the pixel format and cannot assume the stride is the same as the Width. The pixel data is only ever a byte if it uses 8bpp, that is very uncommon. Consider to get ahead by picking the fast-and-convenient pixel format, pass 32bppArgb to LockBits(). Now you can store and address the pixels with an int array and stride no longer matters.
– Hans Passant
Nov 13 '18 at 11:56
1
Thanks for correct my stride! But even if i correct that, it not answering my question why i get exception in that Bitmap constructor
– michasaucer
Nov 13 '18 at 12:05
1
The IntPtr becomes invalid as soon as you call UnlockBits(). Consider to get ahead by using LockBits and Marshal.Copy again, now copying the other way around. Or by not using an array at all and party on the int* directly, more efficient that way.
– Hans Passant
Nov 13 '18 at 13:02
1
Ok, i get it. So there is no efficient way to move byte array with pointer from another func? i need to do it in same method that i modify array? I used lock bits before, but i do all stuff (initializing byte from bitmap) in one method, now in refactor way i wanted to move that thing away
– michasaucer
Nov 13 '18 at 13:10
1
You have to throw away what you have and write version 2. You'll get there.
– Hans Passant
Nov 13 '18 at 13:13