public override void OnResize(int sx, int sy) { Bounds = new rect_d(0, 0, sx, sy);; int bitDepth = GetBitDepthForPixelFormat(m_format); backBuffer.Allocate((int)Width, (int)Height, (int)Width * bitDepth / 8, bitDepth); NewGraphics2D().Clear(new RGBA_Doubles(1, 1, 1, 1)); }
/// <summary> /// Download an image from the web into the specified ImageBuffer /// </summary> /// <param name="uri"></param> public void DownloadToImageAsync(ImageBuffer imageToLoadInto, string uriToLoad, bool scaleToImageX, IRecieveBlenderByte scalingBlender = null) { if (scalingBlender == null) { scalingBlender = new BlenderBGRA(); } WebClient client = new WebClient(); client.DownloadDataCompleted += (object sender, DownloadDataCompletedEventArgs e) => { try // if we get a bad result we can get a target invocation exception. In that case just don't show anything { // scale the loaded image to the size of the target image byte[] raw = e.Result; Stream stream = new MemoryStream(raw); ImageBuffer unScaledImage = new ImageBuffer(10, 10); if (scaleToImageX) { StaticData.Instance.LoadImageData(stream, unScaledImage); // If the source image (the one we downloaded) is more than twice as big as our dest image. while (unScaledImage.Width > imageToLoadInto.Width * 2) { // The image sampler we use is a 2x2 filter so we need to scale by a max of 1/2 if we want to get good results. // So we scale as many times as we need to to get the Image to be the right size. // If this were going to be a non-uniform scale we could do the x and y separately to get better results. ImageBuffer halfImage = new ImageBuffer(unScaledImage.Width / 2, unScaledImage.Height / 2, 32, scalingBlender); halfImage.NewGraphics2D().Render(unScaledImage, 0, 0, 0, halfImage.Width / (double)unScaledImage.Width, halfImage.Height / (double)unScaledImage.Height); unScaledImage = halfImage; } double finalScale = imageToLoadInto.Width / (double)unScaledImage.Width; imageToLoadInto.Allocate(imageToLoadInto.Width, (int)(unScaledImage.Height * finalScale), imageToLoadInto.Width * (imageToLoadInto.BitDepth / 8), imageToLoadInto.BitDepth); imageToLoadInto.NewGraphics2D().Render(unScaledImage, 0, 0, 0, finalScale, finalScale); } else { StaticData.Instance.LoadImageData(stream, imageToLoadInto); } imageToLoadInto.MarkImageChanged(); } catch { } }; try { client.DownloadDataAsync(new Uri(uriToLoad)); } catch { } }
private static void LoadImageInto(ImageBuffer imageToLoadInto, bool scaleToImageX, IRecieveBlenderByte scalingBlender, Stream stream) { if (scalingBlender == null) { scalingBlender = new BlenderBGRA(); } ImageBuffer unScaledImage = new ImageBuffer(10, 10); if (scaleToImageX) { lock (locker) { // scale the loaded image to the size of the target image StaticData.Instance.LoadImageData(stream, unScaledImage); } // If the source image (the one we downloaded) is more than twice as big as our dest image. while (unScaledImage.Width > imageToLoadInto.Width * 2) { // The image sampler we use is a 2x2 filter so we need to scale by a max of 1/2 if we want to get good results. // So we scale as many times as we need to get the Image to be the right size. // If this were going to be a non-uniform scale we could do the x and y separately to get better results. ImageBuffer halfImage = new ImageBuffer(unScaledImage.Width / 2, unScaledImage.Height / 2, 32, scalingBlender); halfImage.NewGraphics2D().Render(unScaledImage, 0, 0, 0, halfImage.Width / (double)unScaledImage.Width, halfImage.Height / (double)unScaledImage.Height); unScaledImage = halfImage; } double finalScale = imageToLoadInto.Width / (double)unScaledImage.Width; imageToLoadInto.Allocate(imageToLoadInto.Width, (int)(unScaledImage.Height * finalScale), imageToLoadInto.Width * (imageToLoadInto.BitDepth / 8), imageToLoadInto.BitDepth); imageToLoadInto.NewGraphics2D().Render(unScaledImage, 0, 0, 0, finalScale, finalScale); } else { StaticData.Instance.LoadImageData(stream, imageToLoadInto); } imageToLoadInto.MarkImageChanged(); }
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 { byte[] destBuffer = destImage.GetBuffer(out int 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); }
public 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 { byte[] destBuffer = destImage.GetBuffer(out int 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 { byte[] destBuffer = destImage.GetBuffer(out int 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); }
private void RebuildIntensityToAlphaImage(ImageBuffer sourceImage, ImageBuffer alphaImage, ImageBuffer displayImage) { if (sourceImage == null) { return; } // build the alpha image if (alphaImage.Width != sourceImage.Width || alphaImage.Height != sourceImage.Height) { alphaImage.Allocate(sourceImage.Width, sourceImage.Height, sourceImage.BitDepth, sourceImage.GetRecieveBlender()); displayImage.Allocate(sourceImage.Width, sourceImage.Height, sourceImage.BitDepth, sourceImage.GetRecieveBlender()); } var startInt = (int)(RangeStart * 255); var endInt = (int)(RangeEnd * 255); var rangeInt = (int)Math.Max(1, (RangeEnd - RangeStart) * 255); byte GetAlphaFromIntensity(byte r, byte g, byte b) { // return (color.Red0To1 * 0.2989) + (color.Green0To1 * 0.1140) + (color.Blue0To1 * 0.5870); var alpha = (r * 76 + g * 29 + b * 150) / 255; if (alpha < startInt) { return(0); } else if (alpha > endInt) { return(0); } else { if (rangeInt > 64) { var s1 = 255 - Math.Min(255, ((alpha - startInt) * 255 / rangeInt)); return((byte)s1); } return(255); } } byte[] sourceBuffer = sourceImage.GetBuffer(); byte[] destBuffer = alphaImage.GetBuffer(); Parallel.For(0, sourceImage.Height, (y) => { int imageOffset = sourceImage.GetBufferOffsetY(y); for (int x = 0; x < sourceImage.Width; x++) { int imageBufferOffsetWithX = imageOffset + x * 4; var b = sourceBuffer[imageBufferOffsetWithX + 0]; var g = sourceBuffer[imageBufferOffsetWithX + 1]; var r = sourceBuffer[imageBufferOffsetWithX + 2]; var a = sourceBuffer[imageBufferOffsetWithX + 3]; destBuffer[imageBufferOffsetWithX + 0] = b; destBuffer[imageBufferOffsetWithX + 1] = g; destBuffer[imageBufferOffsetWithX + 2] = r; destBuffer[imageBufferOffsetWithX + 3] = (byte)(GetAlphaFromIntensity(r, g, b) * a / 255); } }); alphaImage.MarkImageChanged(); byte[] displayBuffer = displayImage.GetBuffer(); Parallel.For(0, sourceImage.Height, (y) => { int imageOffset = displayImage.GetBufferOffsetY(y); for (int x = 0; x < displayImage.Width; x++) { int imageBufferOffsetWithX = imageOffset + x * 4; displayBuffer[imageBufferOffsetWithX + 0] = destBuffer[imageBufferOffsetWithX + 0]; displayBuffer[imageBufferOffsetWithX + 1] = destBuffer[imageBufferOffsetWithX + 1]; displayBuffer[imageBufferOffsetWithX + 2] = destBuffer[imageBufferOffsetWithX + 2]; if (destBuffer[imageBufferOffsetWithX + 3] > 1) { displayBuffer[imageBufferOffsetWithX + 3] = 255; } else { displayBuffer[imageBufferOffsetWithX + 3] = 0; } } }); displayImage.MarkImageChanged(); }