This might be a simple one, but I can't seem to find an easy way to do it. I need to save an array of 84 uint's into an SQL database's BINARY field. So I'm using the following lines in my C# ASP.NET project:
//This is what I have
uint[] uintArray;
//I need to convert from uint[] to byte[]
byte[] byteArray = ???
cmd.Parameters.Add("#myBindaryData", SqlDbType.Binary).Value = byteArray;
So how do you convert from uint[] to byte[]?
How about:
byte[] byteArray = uintArray.SelectMany(BitConverter.GetBytes).ToArray();
This'll do what you want, in little-endian format...
You can use System.Buffer.BlockCopy to do this:
byte[] byteArray = new byte[uintArray.Length * 4];
Buffer.BlockCopy(uintArray, 0, byteArray, 0, uintArray.Length * 4];
http://msdn.microsoft.com/en-us/library/system.buffer.blockcopy.aspx
This will be much more efficient than using a for loop or some similar construct. It directly copies the bytes from the first array to the second.
To convert back just do the same thing in reverse.
There is no built-in conversion function to do this. Because of the way arrays work, a whole new array will need to be allocated and its values filled-in. You will probably just have to write that yourself. You can use the System.BitConverter.GetBytes(uint) function to do some of the work, and then copy the resulting values into the final byte[].
Here's a function that will do the conversion in little-endian format:
private static byte[] ConvertUInt32ArrayToByteArray(uint[] value)
{
const int bytesPerUInt32 = 4;
byte[] result = new byte[value.Length * bytesPerUInt32];
for (int index = 0; index < value.Length; index++)
{
byte[] partialResult = System.BitConverter.GetBytes(value[index]);
for (int indexTwo = 0; indexTwo < partialResult.Length; indexTwo++)
result[index * bytesPerUInt32 + indexTwo] = partialResult[indexTwo];
}
return result;
}
byte[] byteArray = Array.ConvertAll<uint, byte>(
uintArray,
new Converter<uint, byte>(
delegate(uint u) { return (byte)u; }
));
Heed advice from #liho1eye, make sure your uints really fit into bytes, otherwise you're losing data.
If you need all the bits from each uint, you're gonna to have to make an appropriately sized byte[] and copy each uint into the four bytes it represents.
Something like this ought to work:
uint[] uintArray;
//I need to convert from uint[] to byte[]
byte[] byteArray = new byte[uintArray.Length * sizeof(uint)];
for (int i = 0; i < uintArray.Length; i++)
{
byte[] barray = System.BitConverter.GetBytes(uintArray[i]);
for (int j = 0; j < barray.Length; j++)
{
byteArray[i * sizeof(uint) + j] = barray[j];
}
}
cmd.Parameters.Add("#myBindaryData", SqlDbType.Binary).Value = byteArray;
Related
I'm trying to copy a specific amount of bytes from one byte array, to another byte array, I've searched through numerous answers to similar questions, but can't seem to find a solution.
Basic example of code,
byte[] data = new byte[1024];
int bytes = stream.Read(data, 0, data.Length);
byte[] store;
if I do
Console.WriteLine(bytes);
it will return the number of bytes read from stream which is
24
which is the only bytes I would need to pass over to the ' store ' array.. but of course if i specify
byte[] store = data;
then it will take 1024 bytes, 1000 of which are empty.
so what I want really is something like
byte[] store = (data, 0, bytes);
which would provide store 24 bytes from the data array.
You could use Array.Copy:
byte[] newArray = new byte[length];
Array.Copy(oldArray, startIndex, newArray, 0, length);
or Buffer.BlockCopy:
byte[] newArray = new byte[length];
Buffer.BlockCopy(oldArray, startIndex, newArray, 0, length);
Or LINQ:
var newArray = oldArray
.Skip(startIndex) // skip the first n elements
.Take(length) // take n elements
.ToArray(); // produce array
Try them online
Alternatively, if you're using C# 7.2 or newer (and have the System.Memory NuGet package referenced if you're using .NET Framework), you could use Span<T>:
var newArray = new Span<byte>(oldArray, startIndex, length).ToArray();
Or, if you want, you can just pass the Span<T> around without converting it to an array.
Are you looking for something like this?
byte[] Slice(byte[] source, int start, int len)
{
byte[] res = new byte[len];
for (int i = 0; i < len; i++)
{
res[i] = source[i + start];
}
return res;
}
I want to convert a two dimensional int array to a byte array. what is the most simple way to do so? Example:
int[,] array = new int[2, 2] { { 2, 1 }, { 0, 1 } };
How can i convert array to a byte[]? On your answer, please include also the reverse function to that. (if there is a function to convert an int[,] to a byte[] please show me also how to convert a byte[] to an int[,] )
If you're asking yourself why do i need to do it: i need to send a int[,] over a TCP client to a server, then send a response to the client
PS: I thought about making a [Serializeable] class, which will contain the int[,], then serialize the class into a file and send that file, on the server side i will deserialize that file and get the array from there. but i thought that it would take a lot more resrouces to do that then just converting it to a byte[].
Thank you for your help! :)
Short answer: Buffer.BlockCopy.
public static byte[] ToBytes<T>(this T[,] array) where T : struct
{
var buffer = new byte[array.GetLength(0) * array.GetLength(1) * System.Runtime.InteropServices.Marshal.SizeOf(typeof(T))];
Buffer.BlockCopy(array, 0, buffer, 0, buffer.Length);
return buffer;
}
public static void FromBytes<T>(this T[,] array, byte[] buffer) where T : struct
{
var len = Math.Min(array.GetLength(0) * array.GetLength(1) * System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), buffer.Length);
Buffer.BlockCopy(buffer, 0, array, 0, len);
}
If you aren't afraid of using unsafe code it's really simple:
int[,] array = new int[2, 2];
//Do whatever to fill the array
byte[] buffer = new byte[array.GetLength(0) * array.GetLength(1) * sizeof(int)];
fixed (void* pArray = &array[0,0])
{
byte* pData = (byte*)pArray;
for (int buc = 0; buc < buffer.Length; buc++)
buffer[buc] = *(pData + buc);
}
I require to convert int[] to byte[] pointer.
The above is required in order to be able to populate the entries of a WriteableBitmap pixel by pixel as below:
//previewBuffer1 is of type byte[]
WriteableBitmap wb1 = new WriteableBitmap(nVidWidth, nVidHeight);
int k=0;
// wb1.Pixels is of type int[] by default
byte* data = (byte*) wb1.Pixels; // ****THIS DOESN'T WORK. THROWS ERROR. HOW CAN I ACCOMPLISH THIS***
for (int i=0; i<nVidHeight; i++){
for (int j=0; j<nVidWidth; j++){
byte grayscaleval = previewBuffer1[k];
data [4*k] = grayscaleval ;
data [4*k + 1] = grayscaleval ;
data [4*k + 2] = grayscaleval ;
k++;
}
}
How do I get a byte* pointer for wb1.Pixels which is of type int[]?
Sounds like you want to treat each int in your array as sequence of bytes - how about BitConverter.GetBytes?
byte[] bytes = BitConverter.GetBytes(intValue);
If you want to avoid array copying etc, use unsafe which allows pointers (you'd need to tick the "Allow unsafe code" checkbox in project properties):
unsafe static void UnsafeConvert(int value)
{
byte* bytes = (byte*)&value;
byte first = bytes[0];
...
}
I'm confused by your loop because I think it has a few problems...but it looks like you are trying to strip the alpha component of RGBA data. Why not do something like:
Assuming you have:
1. a byte [] you want to store RGB data without the Alpha component
2. an int [] source of RGBA data
int offset=0; // offset into the 'dest' array of bytes
for (...) // loop through your source array of ints
{
// get this current int value as rgba_val
int rgba_val = (whatever your RGBA source is..is it wb1.Pixels?)
dest[offset] = (rgba_val & 0xff) >> 24;
dest[offset+1] = (rgba_val & 0x00ff) >> 16;
dest[offset+2] = (rgba_val & 0x0000ff) >> 8;
}
I guess the below will work out for me:
//previewBuffer1 is of type byte[]
WriteableBitmap wb1 = new WriteableBitmap(nVidWidth, nVidHeight);
int k=0;
// wb1.Pixels is of type int[] by default
//byte* data = (byte*) wb1.Pixels; // ****NOT REQUIRED ANYMORE***
for (int i=0; i<nVidHeight; i++){
for (int j=0; j<nVidWidth; j++){
int grayscaleval = (int) previewBuffer1[k];
wb1.Pixels[k] = ((grayscaleval) | (grayscaleval<<8) | (grayscaleval<<16) | (0xFF<<24)); // 0xFF is for alpha blending value
k++;
}
}
Atleast logically seems to be fine. Yet to try it out.
Use this to convert your int array into bytes array
WriteableBitmap wb1 = new WriteableBitmap(100, 100);
int[] pixels = wb1.Pixels;
byte[] data = new byte[pixels.Length];
for (int i= 0; i < pixels.Length;i ++)
{
data[i] = (byte)pixels[i];
}
I have a .dll(not my own) that has a delegate. This delegate Callback function is:
"CallBackFN(ushort opCOde, IntPtr payload, uint size, uint localIP)"
How can i convert IntPtr to Byte[]? I think that payload is actually Byte[]. If it's not Byte[] and it's something else would i lose some data?
If it's a byte[] array:
byte[] managedArray = new byte[size];
Marshal.Copy(pnt, managedArray, 0, size);
If it's not byte[], the size parameter in of Marshal.Copy is the number of elements in the array, not the byte size. So, if you had an int[] array rather than a byte[] array, you would have to divide by 4 (bytes per int) to get the correct number of elements to copy, assuming your size parameter passed through the callback refers to the number of bytes.
If you need performance, use it directly:
unsafe {
byte *ptr = (byte *)buffer.ToPointer();
int offset = 0;
for (int i=0; i<height; i++)
{
for (int j=0; j<width; j++)
{
float b = (float)ptr[offset+0] / 255.0f;
float g = (float)ptr[offset+1] / 255.0f;
float r = (float)ptr[offset+2] / 255.0f;
float a = (float)ptr[offset+3] / 255.0f;
offset += 4;
UnityEngine.Color color = new UnityEngine.Color(r, g, b, a);
texture.SetPixel(j, height-i, color);
}
}
}
Have you looked into Marshal.Copy?
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.copy.aspx
According to this Stack Overflow question, you can do the following:
var byteArray = new byte[dataBlockSize];
System.Runtime.InteropServices.Marshal.Copy(payload, byteArray, 0, dataBlockSize);
Span<byte> may be a better solution as it provides most features you need from a byte array. It is faster as you won't need to allocate and copy to a new buffer and safer as you will not have to use directly the pointer.
IntPtr ptr = ... ;
int ptrLength = ...;
unsafe
{
Span<byte> byteArray = new Span<byte>(ptr.ToPointer(), ptrLength);
for (int i = 0; i < byteArray.Length; i++ )
{
// Use it as normalarray array ;
byteArray[i] = 6;
}
// You can always get a byte array . Caution, it allocates a new buffer
byte[] realByteArray = byteArray.ToArray();
}
It's included in.NET Core 2.1 and a nuget package (System.Memory) for .NET Framework 4.5 + and .NET Core 2.0 +;
You can use Marshal.Copy Method (IntPtr, Byte[], Int32, Int32)
How to convert an int[,] to byte[] in C#?
Some code will be appreciated
EDIT:
I need a function to perform the following:
byte[] FuncName (int[,] Input)
Since there is very little detail in your question, I can only guess what you're trying to do... Assuming you want to "flatten" a 2D array of ints into a 1D array of bytes, you can do something like that :
byte[] Flatten(int[,] input)
{
return input.Cast<int>().Select(i => (byte)i).ToArray();
}
Note the call to Cast : that's because multidimensional arrays implement IEnumerable but not IEnumerable<T>
It seem that you are writing the types wrong, but here is what you might be looking for:
byte[] FuncName (int[,] input)
{
byte[] byteArray = new byte[input.Length];
int idx = 0;
foreach (int v in input) {
byteArray[idx++] = (byte)v;
}
return byteArray;
}
Here's an implementation that assumes you are attempting serialization; no idea if this is what you want, though; it prefixes the dimensions, then each cell using basic encoding:
public byte[] Encode(int[,] input)
{
int d0 = input.GetLength(0), d1 = input.GetLength(1);
byte[] raw = new byte[((d0 * d1) + 2) * 4];
Buffer.BlockCopy(BitConverter.GetBytes(d0), 0, raw, 0, 4);
Buffer.BlockCopy(BitConverter.GetBytes(d1), 0, raw, 4, 4);
int offset = 8;
for(int i0 = 0 ; i0 < d0 ; i0++)
for (int i1 = 0; i1 < d1; i1++)
{
Buffer.BlockCopy(BitConverter.GetBytes(input[i0,i1]), 0,
raw, offset, 4);
offset += 4;
}
return raw;
}
The BitConverter converts primitive types to byte arrays:
byte[] myByteArray = System.BitConverter.GetBytes(myInt);
You appear to want a 2 dimensional array of ints to be converted to bytes. Combine the BitConverter with the requisite loop construct (e.g foreach) and whatever logic you want to combine the array dimensions.