Splitting byte [] into multiple bytes [] of arrays in C #

I am trying to "crop" image bytes. This will allow me to upload a large image in parts. I have an image that is currently stored as one large byte []. I would like to split the byte array into byte[] with a maximum length of 512 elements. However, I am not sure how to do this in the most efficient way.

Does anyone know how I can do this in the most efficient way?

+6
source share
4 answers

The most effective method would be: do not do this. If you already have an image in the form of a single byte [], then for the local code it is usually enough to specify the offset and length (perhaps som ArraySegment-by-byte). If your download API accepts only byte [], you should still not completely break it; just use one 512 buffer and use Buffer.BlockCopy to load its consecutive chunks of data. You may need to resize (Array.Resize) the last fragment, but not more than 2 arrays.

Even better; first, avoid using the byte []: consider downloading data through the streaming API (this will work well if the data comes from a file); just use Read (in a loop, processing the return value, etc.) to fill in the pieces of max 512. For example (untested, just illustrative):

 byte[] buffer = new byte[512]; while(true) { int space = 512, read, offset = 0; while(space > 0 && (read = stream.Read(buffer, offset, space)) > 0) { space -= read; offset += read; } // either a full buffer, or EOF if(space != 0) { // EOF - final if(offset != 0) { // something to send Array.Resize(red buffer, offset); Upload(buffer); } break; } else { // full buffer Upload(buffer); } } 
+6
source

I wrote an extension for this, initially for strings, but decided to make it general.

  public static T[] CopySlice<T>(this T[] source, int index, int length, bool padToLength = false) { int n = length; T[] slice = null; if (source.Length < index + length) { n = source.Length - index; if (padToLength) { slice = new T[length]; } } if(slice == null) slice = new T[n]; Array.Copy(source, index, slice, 0, n); return slice; } public static IEnumerable<T[]> Slices<T>(this T[] source, int count, bool padToLength = false) { for (var i = 0; i < source.Length; i += count) yield return source.CopySlice(i, count, padToLength); } 

Basically, you can use it like this:

 byte[] myBytes; // original byte array foreach(byte[] copySlice in myBytes.Slices(10)) { // do something with each slice } 

Change I also provided an answer to SO using Buffer.BlockCopy here , but BlockCopy will only work with byte[] arrays, so the standard version for strings will not be possible.

+11
source
 public static IEnumerable<byte[]> Split(this byte[] value,int bufferLength){ int countOfArray = value.Length / bufferLength; if(value.Length % bufferLength > 0) countOfArray ++; for(int i=0;i<countOfArray;i++) { yield return value.Skip(i * bufferLength).Take(bufferLength).ToArray(); } } 

This is my extension that I used

+4
source

I know this is old, but the same solution is needed, and the following works fine for me, hope this helps

 private byte[][] ByteArrayToChunks(byte[] byteData, long BufferSize) { byte[][] chunks = byteData.Select((value, index) => new { PairNum = Math.Floor(index / (double)BufferSize), value }).GroupBy(pair => pair.PairNum).Select(grp => grp.Select(g => g.value).ToArray()).ToArray(); return chunks; } 
+1
source

Source: https://habr.com/ru/post/922157/


All Articles