public static bool ConvertImageToImageBuffer(ImageBuffer destImage, int width, int height, Rgba32[] pixelArray) { if (pixelArray != null) { destImage.Allocate(width, height, width * 4, 32); if (destImage.GetRecieveBlender() == null) { destImage.SetRecieveBlender(new BlenderBGRA()); } int sourceIndex = 0; byte[] destBuffer = destImage.GetBuffer(out _); for (int y = 0; y < destImage.Height; y++) { int destIndex = destImage.GetBufferOffsetXY(0, destImage.Height - 1 - y); for (int x = 0; x < destImage.Width; x++) { destBuffer[destIndex++] = pixelArray[sourceIndex].B; destBuffer[destIndex++] = pixelArray[sourceIndex].G; destBuffer[destIndex++] = pixelArray[sourceIndex].R; destBuffer[destIndex++] = pixelArray[sourceIndex].A; sourceIndex++; } } return(true); } return(false); }
/// <summary> /// This will create a new ImageBuffer that references the same memory as the image that you took the sub image from. /// It will modify the original main image when you draw to it. /// </summary> /// <param name="imageContainingSubImage"></param> /// <param name="subImageBounds"></param> /// <returns></returns> public static ImageBuffer NewSubImageReference(IImageByte imageContainingSubImage, RectangleDouble subImageBounds) { ImageBuffer subImage = new ImageBuffer(); if (subImageBounds.Left < 0 || subImageBounds.Bottom < 0 || subImageBounds.Right > imageContainingSubImage.Width || subImageBounds.Top > imageContainingSubImage.Height || subImageBounds.Left >= subImageBounds.Right || subImageBounds.Bottom >= subImageBounds.Top) { throw new ArgumentException("The subImageBounds must be on the image and valid."); } int left = Math.Max(0, (int)Math.Floor(subImageBounds.Left)); int bottom = Math.Max(0, (int)Math.Floor(subImageBounds.Bottom)); int width = Math.Min(imageContainingSubImage.Width - left, (int)subImageBounds.Width); int height = Math.Min(imageContainingSubImage.Height - bottom, (int)subImageBounds.Height); int bufferOffsetToFirstPixel = imageContainingSubImage.GetBufferOffsetXY(left, bottom); subImage.AttachBuffer(imageContainingSubImage.GetBuffer(), bufferOffsetToFirstPixel, width, height, imageContainingSubImage.StrideInBytes(), imageContainingSubImage.BitDepth, imageContainingSubImage.GetBytesBetweenPixelsInclusive()); subImage.SetRecieveBlender(imageContainingSubImage.GetRecieveBlender()); return(subImage); }
public void LoadImage(string path, ImageBuffer destImage) { ImageBuffer cachedImage = null; if (!cachedImages.TryGetValue(path, out cachedImage)) { using (var imageStream = OpenSteam(path)) { var bitmap = new Bitmap(imageStream); cachedImage = new ImageBuffer(); ImageIOWindowsPlugin.ConvertBitmapToImage(cachedImage, bitmap); } if (cachedImage.Width < 200 && cachedImage.Height < 200) { // only cache relatively small images cachedImages.Add(path, cachedImage); } } destImage.Allocate(cachedImage.Width, cachedImage.Height, cachedImage.StrideInBytesAbs(), cachedImage.BitDepth); destImage.SetRecieveBlender(cachedImage.GetRecieveBlender()); destImage.CopyFrom(cachedImage); }
private static void Copy8BitDataToImage(ImageBuffer destImage, Bitmap bitmap) { destImage.Allocate(bitmap.Width, bitmap.Height, bitmap.Width * 4, 32); if (destImage.GetRecieveBlender() == null) { destImage.SetRecieveBlender(new BlenderBGRA()); } BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat); int sourceIndex = 0; int destIndex = 0; unsafe { int offset; byte[] destBuffer = destImage.GetBuffer(out offset); byte * pSourceBuffer = (byte *)bitmapData.Scan0; System.Drawing.Color[] colors = bitmap.Palette.Entries; for (int y = 0; y < destImage.Height; y++) { sourceIndex = y * bitmapData.Stride; destIndex = destImage.GetBufferOffsetY(destImage.Height - 1 - y); for (int x = 0; x < destImage.Width; x++) { System.Drawing.Color color = colors[pSourceBuffer[sourceIndex++]]; destBuffer[destIndex++] = color.B; destBuffer[destIndex++] = color.G; destBuffer[destIndex++] = color.R; destBuffer[destIndex++] = color.A; } } } bitmap.UnlockBits(bitmapData); }
private static bool ConvertBitmapToImage(ImageBuffer destImage, Bitmap m_WidowsBitmap) { if (m_WidowsBitmap != null) { switch (m_WidowsBitmap.PixelFormat) { case System.Drawing.Imaging.PixelFormat.Format32bppArgb: { destImage.Allocate(m_WidowsBitmap.Width, m_WidowsBitmap.Height, m_WidowsBitmap.Width * 4, 32); if (destImage.GetRecieveBlender() == null) { destImage.SetRecieveBlender(new BlenderBGRA()); } BitmapData bitmapData = m_WidowsBitmap.LockBits(new Rectangle(0, 0, m_WidowsBitmap.Width, m_WidowsBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, m_WidowsBitmap.PixelFormat); int sourceIndex = 0; int destIndex = 0; unsafe { int offset; byte[] destBuffer = destImage.GetBuffer(out offset); byte* pSourceBuffer = (byte*)bitmapData.Scan0; for (int y = 0; y < destImage.Height; y++) { destIndex = destImage.GetBufferOffsetXY(0, destImage.Height - 1 - y); for (int x = 0; x < destImage.Width; x++) { #if true destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; #else RGBA_Bytes notPreMultiplied = new RGBA_Bytes(pSourceBuffer[sourceIndex + 0], pSourceBuffer[sourceIndex + 1], pSourceBuffer[sourceIndex + 2], pSourceBuffer[sourceIndex + 3]); sourceIndex += 4; RGBA_Bytes preMultiplied = notPreMultiplied.GetAsRGBA_Floats().premultiply().GetAsRGBA_Bytes(); destBuffer[destIndex++] = preMultiplied.blue; destBuffer[destIndex++] = preMultiplied.green; destBuffer[destIndex++] = preMultiplied.red; destBuffer[destIndex++] = preMultiplied.alpha; #endif } } } m_WidowsBitmap.UnlockBits(bitmapData); return true; } case System.Drawing.Imaging.PixelFormat.Format24bppRgb: { destImage.Allocate(m_WidowsBitmap.Width, m_WidowsBitmap.Height, m_WidowsBitmap.Width * 4, 32); BitmapData bitmapData = m_WidowsBitmap.LockBits(new Rectangle(0, 0, m_WidowsBitmap.Width, m_WidowsBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, m_WidowsBitmap.PixelFormat); int sourceIndex = 0; int destIndex = 0; unsafe { int offset; byte[] destBuffer = destImage.GetBuffer(out offset); byte* pSourceBuffer = (byte*)bitmapData.Scan0; for (int y = 0; y < destImage.Height; y++) { sourceIndex = y * bitmapData.Stride; destIndex = destImage.GetBufferOffsetXY(0, destImage.Height - 1 - y); for (int x = 0; x < destImage.Width; x++) { destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = 255; } } } m_WidowsBitmap.UnlockBits(bitmapData); return true; } case System.Drawing.Imaging.PixelFormat.Format8bppIndexed: { Copy8BitDataToImage(destImage, m_WidowsBitmap); return true; } default: throw new System.NotImplementedException(); } } return false; }
private static int LowLevelReadTGABitsFromBuffer(ImageBuffer imageToReadTo, byte[] wholeFileBuffer, int DestBitDepth) { STargaHeader TargaHeader = new STargaHeader(); int FileReadOffset; if (!ReadTGAInfo(wholeFileBuffer, out TargaHeader)) { return(0); } // if the frame we are loading is different then the one we have allocated // or we don't have any bits allocated if ((imageToReadTo.Width * imageToReadTo.Height) != (TargaHeader.Width * TargaHeader.Height)) { imageToReadTo.Allocate(TargaHeader.Width, TargaHeader.Height, TargaHeader.Width * DestBitDepth / 8, DestBitDepth); } // work out the line width switch (imageToReadTo.BitDepth) { case 24: TGABytesPerLine = imageToReadTo.Width * 3; if (imageToReadTo.GetRecieveBlender() == null) { imageToReadTo.SetRecieveBlender(new BlenderBGR()); } break; case 32: TGABytesPerLine = imageToReadTo.Width * 4; if (imageToReadTo.GetRecieveBlender() == null) { imageToReadTo.SetRecieveBlender(new BlenderBGRA()); } break; default: throw new System.Exception("Bad bit depth."); } if (TGABytesPerLine > 0) { byte[] BufferToDecompressTo = null; FileReadOffset = TargaHeaderSize + TargaHeader.PostHeaderSkip; if (TargaHeader.ImageType == 10) // 10 is RLE compressed { BufferToDecompressTo = new byte[TGABytesPerLine * 2]; } // read all the lines * for (int i = 0; i < imageToReadTo.Height; i++) { byte[] BufferToCopyFrom; int CopyOffset = 0; int CurReadLine; // bit 5 tells us if the image is stored top to bottom or bottom to top if ((TargaHeader.Descriptor & 0x20) != 0) { // bottom to top CurReadLine = imageToReadTo.Height - i - 1; } else { // top to bottom CurReadLine = i; } if (TargaHeader.ImageType == 10) // 10 is RLE compressed { FileReadOffset = Decompress(BufferToDecompressTo, wholeFileBuffer, FileReadOffset, imageToReadTo.Width, TargaHeader.BPP, CurReadLine); BufferToCopyFrom = BufferToDecompressTo; } else { BufferToCopyFrom = wholeFileBuffer; CopyOffset = FileReadOffset; } int bufferOffset; byte[] imageBuffer = imageToReadTo.GetBuffer(out bufferOffset); switch (imageToReadTo.BitDepth) { case 8: switch (TargaHeader.BPP) { case 24: Do24To8Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; case 32: Do32To8Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; } break; case 24: switch (TargaHeader.BPP) { case 24: Do24To24Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; case 32: Do32To24Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; } break; case 32: switch (TargaHeader.BPP) { case 24: Do24To32Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; case 32: Do32To32Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; } break; default: throw new System.Exception("Bad bit depth"); } if (TargaHeader.ImageType != 10) // 10 is RLE compressed { FileReadOffset += TGABytesPerLine; } } } return(TargaHeader.Width); }
public static void DoAllWhite(ImageBuffer result, ImageBuffer imageA) { if (imageA.BitDepth != result.BitDepth) { throw new NotImplementedException("All the images have to be the same bit depth."); } if (imageA.Width != result.Width || imageA.Height != result.Height) { throw new Exception("All images must be the same size."); } switch (imageA.BitDepth) { case 32: { int height = imageA.Height; int width = imageA.Width; byte[] resultBuffer = result.GetBuffer(); byte[] imageABuffer = imageA.GetBuffer(); for (int y = 0; y < height; y++) { int offsetA = imageA.GetBufferOffsetY(y); int offsetResult = result.GetBufferOffsetY(y); for (int x = 0; x < width; x++) { int alpha = imageABuffer[offsetA+3]; if (alpha > 0) { resultBuffer[offsetResult++] = (byte)255; offsetA++; resultBuffer[offsetResult++] = (byte)255; offsetA++; resultBuffer[offsetResult++] = (byte)255; offsetA++; resultBuffer[offsetResult++] = (byte)alpha; offsetA++; } else { resultBuffer[offsetResult++] = (byte)0; offsetA++; resultBuffer[offsetResult++] = (byte)0; offsetA++; resultBuffer[offsetResult++] = (byte)0; offsetA++; resultBuffer[offsetResult++] = (byte)0; offsetA++; } } } result.SetRecieveBlender(new BlenderPreMultBGRA()); } break; default: throw new NotImplementedException(); } }
private static ImageBuffer BuildImageFromMeshGroups(List<MeshGroup> loadedMeshGroups, string stlHashCode, Point2D size) { if (loadedMeshGroups != null && loadedMeshGroups.Count > 0 && loadedMeshGroups[0].Meshes != null && loadedMeshGroups[0].Meshes[0] != null) { ImageBuffer tempImage = new ImageBuffer(size.x, size.y); Graphics2D partGraphics2D = tempImage.NewGraphics2D(); partGraphics2D.Clear(new RGBA_Bytes()); AxisAlignedBoundingBox aabb = loadedMeshGroups[0].GetAxisAlignedBoundingBox(); for (int meshGroupIndex = 1; meshGroupIndex < loadedMeshGroups.Count; meshGroupIndex++) { aabb = AxisAlignedBoundingBox.Union(aabb, loadedMeshGroups[meshGroupIndex].GetAxisAlignedBoundingBox()); } double maxSize = Math.Max(aabb.XSize, aabb.YSize); double scale = size.x / (maxSize * 1.2); RectangleDouble bounds2D = new RectangleDouble(aabb.minXYZ.x, aabb.minXYZ.y, aabb.maxXYZ.x, aabb.maxXYZ.y); foreach (MeshGroup meshGroup in loadedMeshGroups) { foreach (Mesh loadedMesh in meshGroup.Meshes) { PolygonMesh.Rendering.OrthographicZProjection.DrawTo(partGraphics2D, loadedMesh, new Vector2((size.x / scale - bounds2D.Width) / 2 - bounds2D.Left, (size.y / scale - bounds2D.Height) / 2 - bounds2D.Bottom), scale, RGBA_Bytes.White); } } if (File.Exists("RunUnitTests.txt")) { foreach (Mesh loadedMesh in loadedMeshGroups[0].Meshes) { List<MeshEdge> nonManifoldEdges = loadedMesh.GetNonManifoldEdges(); if (nonManifoldEdges.Count > 0) { partGraphics2D.Circle(size.x / 4, size.x / 4, size.x / 8, RGBA_Bytes.Red); } } } tempImage.SetRecieveBlender(new BlenderPreMultBGRA()); AllWhite.DoAllWhite(tempImage); // and give it back return tempImage; } return null; }
private static unsafe int LowLevelReadTGABitsFromBuffer(ImageBuffer imageToReadTo, byte[] wholeFileBuffer, int DestBitDepth) { STargaHeader TargaHeader = new STargaHeader(); int FileReadOffset; if (!ReadTGAInfo(wholeFileBuffer, out TargaHeader)) { return 0; } // if the frame we are loading is different then the one we have allocated // or we don't have any bits allocated if ((imageToReadTo.Width * imageToReadTo.Height) != (TargaHeader.Width * TargaHeader.Height)) { imageToReadTo.Allocate(TargaHeader.Width, TargaHeader.Height, TargaHeader.Width * DestBitDepth / 8, DestBitDepth); } // work out the line width switch (imageToReadTo.BitDepth) { case 24: TGABytesPerLine = imageToReadTo.Width * 3; if (imageToReadTo.GetRecieveBlender() == null) { imageToReadTo.SetRecieveBlender(new BlenderBGR()); } break; case 32: TGABytesPerLine = imageToReadTo.Width * 4; if (imageToReadTo.GetRecieveBlender() == null) { imageToReadTo.SetRecieveBlender(new BlenderBGRA()); } break; default: throw new System.Exception("Bad bit depth."); } if (TGABytesPerLine > 0) { byte[] BufferToDecompressTo = null; FileReadOffset = TargaHeaderSize + TargaHeader.PostHeaderSkip; if (TargaHeader.ImageType == 10) // 10 is RLE compressed { BufferToDecompressTo = new byte[TGABytesPerLine * 2]; } // read all the lines * for (int i = 0; i < imageToReadTo.Height; i++) { byte[] BufferToCopyFrom; int CopyOffset = 0; int CurReadLine; // bit 5 tells us if the image is stored top to bottom or bottom to top if ((TargaHeader.Descriptor & 0x20) != 0) { // bottom to top CurReadLine = imageToReadTo.Height - i - 1; } else { // top to bottom CurReadLine = i; } if (TargaHeader.ImageType == 10) // 10 is RLE compressed { FileReadOffset = Decompress(BufferToDecompressTo, wholeFileBuffer, FileReadOffset, imageToReadTo.Width, TargaHeader.BPP, CurReadLine); BufferToCopyFrom = BufferToDecompressTo; } else { BufferToCopyFrom = wholeFileBuffer; CopyOffset = FileReadOffset; } int bufferOffset; byte[] imageBuffer = imageToReadTo.GetBuffer(out bufferOffset); switch (imageToReadTo.BitDepth) { case 8: switch (TargaHeader.BPP) { case 24: Do24To8Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; case 32: Do32To8Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; } break; case 24: switch (TargaHeader.BPP) { case 24: Do24To24Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; case 32: Do32To24Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; } break; case 32: switch (TargaHeader.BPP) { case 24: Do24To32Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; case 32: Do32To32Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; } break; default: throw new System.Exception("Bad bit depth"); } if (TargaHeader.ImageType != 10) // 10 is RLE compressed { FileReadOffset += TGABytesPerLine; } } } return TargaHeader.Width; }
/// <summary> /// This will create a new ImageBuffer that references the same memory as the image that you took the sub image from. /// It will modify the original main image when you draw to it. /// </summary> /// <param name="imageContainingSubImage"></param> /// <param name="subImageBounds"></param> /// <returns></returns> public static ImageBuffer NewSubImageReference(IImageByte imageContainingSubImage, RectangleDouble subImageBounds) { ImageBuffer subImage = new ImageBuffer(); if (subImageBounds.Left < 0 || subImageBounds.Bottom < 0 || subImageBounds.Right > imageContainingSubImage.Width || subImageBounds.Top > imageContainingSubImage.Height || subImageBounds.Left >= subImageBounds.Right || subImageBounds.Bottom >= subImageBounds.Top) { throw new ArgumentException("The subImageBounds must be on the image and valid."); } int left = Math.Max(0, (int)Math.Floor(subImageBounds.Left)); int bottom = Math.Max(0, (int)Math.Floor(subImageBounds.Bottom)); int width = Math.Min(imageContainingSubImage.Width - left, (int)subImageBounds.Width); int height = Math.Min(imageContainingSubImage.Height - bottom, (int)subImageBounds.Height); int bufferOffsetToFirstPixel = imageContainingSubImage.GetBufferOffsetXY(left, bottom); subImage.AttachBuffer(imageContainingSubImage.GetBuffer(), bufferOffsetToFirstPixel, width, height, imageContainingSubImage.StrideInBytes(), imageContainingSubImage.BitDepth, imageContainingSubImage.GetBytesBetweenPixelsInclusive()); subImage.SetRecieveBlender(imageContainingSubImage.GetRecieveBlender()); return subImage; }
internal static bool ConvertBitmapToImage(ImageBuffer destImage, Bitmap bitmap) { if (bitmap != null) { switch (bitmap.PixelFormat) { case System.Drawing.Imaging.PixelFormat.Format32bppArgb: { destImage.Allocate(bitmap.Width, bitmap.Height, bitmap.Width * 4, 32); if (destImage.GetRecieveBlender() == null) { destImage.SetRecieveBlender(new BlenderBGRA()); } BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat); int sourceIndex = 0; int destIndex = 0; unsafe { int offset; byte[] destBuffer = destImage.GetBuffer(out offset); byte * pSourceBuffer = (byte *)bitmapData.Scan0; for (int y = 0; y < destImage.Height; y++) { destIndex = destImage.GetBufferOffsetXY(0, destImage.Height - 1 - y); for (int x = 0; x < destImage.Width; x++) { #if true destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; #else Color notPreMultiplied = new Color(pSourceBuffer[sourceIndex + 0], pSourceBuffer[sourceIndex + 1], pSourceBuffer[sourceIndex + 2], pSourceBuffer[sourceIndex + 3]); sourceIndex += 4; Color preMultiplied = notPreMultiplied.ToColorF().premultiply().ToColor(); destBuffer[destIndex++] = preMultiplied.blue; destBuffer[destIndex++] = preMultiplied.green; destBuffer[destIndex++] = preMultiplied.red; destBuffer[destIndex++] = preMultiplied.alpha; #endif } } } bitmap.UnlockBits(bitmapData); return(true); } case System.Drawing.Imaging.PixelFormat.Format24bppRgb: { destImage.Allocate(bitmap.Width, bitmap.Height, bitmap.Width * 4, 32); if (destImage.GetRecieveBlender() == null) { destImage.SetRecieveBlender(new BlenderBGRA()); } BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat); int sourceIndex = 0; int destIndex = 0; unsafe { int offset; byte[] destBuffer = destImage.GetBuffer(out offset); byte * pSourceBuffer = (byte *)bitmapData.Scan0; for (int y = 0; y < destImage.Height; y++) { sourceIndex = y * bitmapData.Stride; destIndex = destImage.GetBufferOffsetXY(0, destImage.Height - 1 - y); for (int x = 0; x < destImage.Width; x++) { destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = 255; } } } bitmap.UnlockBits(bitmapData); return(true); } case System.Drawing.Imaging.PixelFormat.Format8bppIndexed: { Copy8BitDataToImage(destImage, bitmap); return(true); } default: // let this code fall through and return false break; } } return(false); }
internal static bool ConvertBitmapToImage(ImageBuffer destImage, Bitmap m_WidowsBitmap) { if (m_WidowsBitmap != null) { switch (m_WidowsBitmap.PixelFormat) { case System.Drawing.Imaging.PixelFormat.Format32bppArgb: { destImage.Allocate(m_WidowsBitmap.Width, m_WidowsBitmap.Height, m_WidowsBitmap.Width * 4, 32); if (destImage.GetRecieveBlender() == null) { destImage.SetRecieveBlender(new BlenderBGRA()); } BitmapData bitmapData = m_WidowsBitmap.LockBits(new Rectangle(0, 0, m_WidowsBitmap.Width, m_WidowsBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, m_WidowsBitmap.PixelFormat); int sourceIndex = 0; int destIndex = 0; unsafe { int offset; byte[] destBuffer = destImage.GetBuffer(out offset); byte * pSourceBuffer = (byte *)bitmapData.Scan0; for (int y = 0; y < destImage.Height; y++) { destIndex = destImage.GetBufferOffsetXY(0, destImage.Height - 1 - y); for (int x = 0; x < destImage.Width; x++) { #if true destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; #else RGBA_Bytes notPreMultiplied = new RGBA_Bytes(pSourceBuffer[sourceIndex + 0], pSourceBuffer[sourceIndex + 1], pSourceBuffer[sourceIndex + 2], pSourceBuffer[sourceIndex + 3]); sourceIndex += 4; RGBA_Bytes preMultiplied = notPreMultiplied.GetAsRGBA_Floats().premultiply().GetAsRGBA_Bytes(); destBuffer[destIndex++] = preMultiplied.blue; destBuffer[destIndex++] = preMultiplied.green; destBuffer[destIndex++] = preMultiplied.red; destBuffer[destIndex++] = preMultiplied.alpha; #endif } } } m_WidowsBitmap.UnlockBits(bitmapData); return(true); } case System.Drawing.Imaging.PixelFormat.Format24bppRgb: { destImage.Allocate(m_WidowsBitmap.Width, m_WidowsBitmap.Height, m_WidowsBitmap.Width * 4, 32); BitmapData bitmapData = m_WidowsBitmap.LockBits(new Rectangle(0, 0, m_WidowsBitmap.Width, m_WidowsBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, m_WidowsBitmap.PixelFormat); int sourceIndex = 0; int destIndex = 0; unsafe { int offset; byte[] destBuffer = destImage.GetBuffer(out offset); byte * pSourceBuffer = (byte *)bitmapData.Scan0; for (int y = 0; y < destImage.Height; y++) { sourceIndex = y * bitmapData.Stride; destIndex = destImage.GetBufferOffsetXY(0, destImage.Height - 1 - y); for (int x = 0; x < destImage.Width; x++) { destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = pSourceBuffer[sourceIndex++]; destBuffer[destIndex++] = 255; } } } m_WidowsBitmap.UnlockBits(bitmapData); return(true); } case System.Drawing.Imaging.PixelFormat.Format8bppIndexed: { Copy8BitDataToImage(destImage, m_WidowsBitmap); return(true); } default: throw new System.NotImplementedException(); } } return(false); }