Converting a two dimensional int array to a byte array - c#

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

Related

Copy bytes from one array to another

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

How to convert from UInt32 array to byte array?

This question only vise versa. For now I got this:
UInt32[] target;
byte[] decoded = new byte[target.Length * 2];
Buffer.BlockCopy(target, 0, decoded, 0, target.Length);
And this doesn't work, I get array filled with 0x00.
I would recommend something like the following:
UInt32[] target;
//Assignments
byte[] decoded = new byte[target.Length * sizeof(uint)];
Buffer.BlockCopy(target, 0, decoded, 0, decoded.Length);
See code:
uint[] target = new uint[] { 1, 2, 3 };
//Assignments
byte[] decoded = new byte[target.Length * sizeof(uint)];
Buffer.BlockCopy(target, 0, decoded, 0, decoded.Length);
for (int i = 0; i < decoded.Length; i++)
{
Console.WriteLine(decoded[i]);
}
Console.ReadKey();
Also see:
Size of values
Int Array to Byte Array
BlockCopy MSDN
You can use BitConverter.GetBytes method for converting a unit to byte
Try this code. It works for me.
UInt32[] target = new UInt32[]{1,2,3};
byte[] decoded = new byte[target.Length * sizeof(UInt32)];
Buffer.BlockCopy(target, 0, decoded, 0, target.Length*sizeof(UInt32));
foreach(byte b in decoded)
{
Console.WriteLine( b);
}
You need to multiple by 4 to create your byte array, since UInt32 is 4 bytes (32 bit). But use BitConverter and fill a list of byte and late you can create an array out of it if you need.
UInt32[] target = new UInt32[] { 1, 2, 3 };
byte[] decoded = new byte[target.Length * 4]; //not required now
List<byte> listOfBytes = new List<byte>();
foreach (var item in target)
{
listOfBytes.AddRange(BitConverter.GetBytes(item));
}
If you need array then:
byte[] decoded = listOfBytes.ToArray();
Your code has a few errors:
UInt32[] target = new uint[] { 1, 2, 3, 4 };
// Error 1:
// You had 2 instead of 4. Each UInt32 is actually 4 bytes.
byte[] decoded = new byte[target.Length * 4];
// Error 2:
Buffer.BlockCopy(
src: target,
srcOffset: 0,
dst: decoded,
dstOffset: 0,
count: decoded.Length // You had target.Length. You want the length in bytes.
);
This should yield what you're expecting.

Convert memorystream to double-array?

I've got a pcm-stream of raw music data from a wave-file and would like to convert it to a double-array (to apply a fft afterwards).
The result I got now contains very high or low double-numbers (1.0E-200 and 1.0E+300) and I'm not sure whether these can be correct.
This is the code I'm using right now:
WaveStream pcm = WaveFormatConversionStream.CreatePcmStream(mp3);
double[] real = new double[pcm.Length];
byte[] buffer = new byte[8];
int count = 0;
while ((read = pcm.Read(buffer, 0, buffer.Length)) > 0)
{
real[count] = BitConverter.ToDouble(buffer, 0);
count++;
}
Your PCM stream is almost certainly 16 bit. So instead of BitConverter.ToDouble use ToInt16 instead. Then divide by 32768.0 to get into the the range +/- 1.0
I realize that this question is old; however, I thought I might offer this alternative approach to calling BitConverter.ToDouble.
public static double[] ToDoubleArray(this byte[] bytes)
{
Debug.Assert(bytes.Length % sizeof(double) == 0, "byte array must be aligned on the size of a double.");
double[] doubles = new double[bytes.Length / sizeof(double)];
GCHandle pinnedDoubles = GCHandle.Alloc(doubles, GCHandleType.Pinned);
Marshal.Copy(bytes, 0, pinnedDoubles.AddrOfPinnedObject(), bytes.Length);
pinnedDoubles.Free();
return doubles;
}
public static double[] ToDoubleArray(this MemoryStream stream)
{
return stream.ToArray().ToDoubleArray();
}

C# convert from uint[] to byte[]

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;

How to convert an int[,] to byte[] in C#

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.

Categories