예제 #1
0
        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));
        }
예제 #2
0
        /// <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
            {
            }
        }
예제 #3
0
        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();
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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();
        }