How to get new Bitmap from Byte Array with IntPtr pointer?












0














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.





  1. First, i load my Bitmap to method that i return byte 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);
    }



  2. 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










share|improve this question


















  • 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
















0














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.





  1. First, i load my Bitmap to method that i return byte 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);
    }



  2. 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










share|improve this question


















  • 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














0












0








0







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.





  1. First, i load my Bitmap to method that i return byte 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);
    }



  2. 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










share|improve this question













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.





  1. First, i load my Bitmap to method that i return byte 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);
    }



  2. 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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 13 '18 at 9:41









michasaucermichasaucer

27413




27413








  • 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




    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












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
});


}
});














draft saved

draft discarded


















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
















draft saved

draft discarded




















































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.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • 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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Bressuire

Vorschmack

Quarantine