Note that there are some explanatory texts on larger screens.

plurals
  1. POC# - reverse image bytes quickly?
    primarykey
    data
    text
    <p>I'm trying to determine the optimal way to flip an image across the Y axis. For every pixel, there are 4 bytes, and each set of 4 bytes needs to remain together in order but get shifted. Here's the best I've come up with so far.</p> <p>This only takes .1-.2s for a 1280x960 image, but with video such performance is crippling. Any suggestions?</p> <p><strong>Initial implementation</strong></p> <pre><code> private void ReverseFrameInPlace(int width, int height, int bytesPerPixel, ref byte[] framePixels) { System.Diagnostics.Stopwatch s = System.Diagnostics.Stopwatch.StartNew(); int stride = width * bytesPerPixel; int halfStride = stride / 2; int byteJump = bytesPerPixel * 2; int length = stride * height; byte pix; for (int i = 0, a = stride, b = stride - bytesPerPixel; i &lt; length; i++) { if (b % bytesPerPixel == 0) { b -= byteJump; } if (i &gt; 0 &amp;&amp; i % halfStride == 0) { i = a; a += stride; b = a - bytesPerPixel; if (i &gt;= length) { break; } } pix = framePixels[i]; framePixels[i] = framePixels[b]; framePixels[b++] = pix; } s.Stop(); System.Console.WriteLine("ReverseFrameInPlace: {0}", s.Elapsed); } </code></pre> <p><strong>Revision #1</strong></p> <p>Revised with indexes and Buffer.BlockCopy per SLaks and Alexei. Also added a Parallel.For since the indexes allow for it.</p> <pre><code> int[] pixelIndexF = null; int[] pixelIndexB = null; private void ReverseFrameInPlace(int width, int height, int bytesPerPixel, byte[] framePixels) { System.Diagnostics.Stopwatch s = System.Diagnostics.Stopwatch.StartNew(); if (pixelIndexF == null)// || pixelIndex.Length != (width * height)) { int stride = width * bytesPerPixel; int length = stride * height; pixelIndexF = new int[width * height / 2]; pixelIndexB = new int[width * height / 2]; for (int i = 0, a = stride, b = stride, index = 0; i &lt; length; i++) { b -= bytesPerPixel; if (i &gt; 0 &amp;&amp; i % (width / 2 )== 0) { //i = a; i += width / 2; a += stride; b = a - bytesPerPixel; if (index &gt;= pixelIndexF.Length) { break; } } pixelIndexF[index] = i * bytesPerPixel; pixelIndexB[index++] = b; } } Parallel.For(0, pixelIndexF.Length, new Action&lt;int&gt;(delegate(int i) { byte[] buffer = new byte[bytesPerPixel]; Buffer.BlockCopy(framePixels, pixelIndexF[i], buffer, 0, bytesPerPixel); Buffer.BlockCopy(framePixels, pixelIndexB[i], framePixels, pixelIndexF[i], bytesPerPixel); Buffer.BlockCopy(buffer, 0, framePixels, pixelIndexB[i], bytesPerPixel); })); s.Stop(); System.Console.WriteLine("ReverseFrameInPlace: {0}", s.Elapsed); } </code></pre> <p><strong>Revision #2</strong></p> <pre><code> private void ReverseFrameInPlace(int width, int height, System.Drawing.Imaging.PixelFormat pixelFormat, byte[] framePixels) { System.Diagnostics.Stopwatch s = System.Diagnostics.Stopwatch.StartNew(); System.Drawing.Rectangle imageBounds = new System.Drawing.Rectangle(0,0,width, height); //create destination bitmap, get handle System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(width, height, pixelFormat); System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(imageBounds, System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat); IntPtr ptr = bitmapData.Scan0; //byte[] to bmap System.Runtime.InteropServices.Marshal.Copy(framePixels, 0, ptr, framePixels.Length); bitmap.UnlockBits(bitmapData); //flip bitmap.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipX); //get handle for bitmap to byte[] bitmapData = bitmap.LockBits(imageBounds, System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat); ptr = bitmapData.Scan0; System.Runtime.InteropServices.Marshal.Copy(ptr, framePixels, 0, framePixels.Length); bitmap.UnlockBits(bitmapData); s.Stop(); System.Console.WriteLine("ReverseFrameInPlace: {0}", s.Elapsed); } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload