Beispiel #1
0
        public override void UpdateNormalBitmap(System.Windows.Media.Imaging.WriteableBitmap bitmap, System.Windows.Media.Color color)
        {
            unsafe
            {
                bitmap.Lock();
                int    currentPixel = -1;
                byte * pStart       = (byte *)(void *)bitmap.BackBuffer;
                double iRowUnit     = (double)(MaxValue - MinValue) / bitmap.PixelHeight;
                double iRowCurrent  = 100;
                double l            = sModel.LComponent(color);
                double a            = sModel.AComponent(color);
                for (int iRow = 0; iRow < bitmap.PixelHeight; iRow++)
                {
                    Color lightness = sModel.Color(l, a, iRowCurrent);
                    for (int iCol = 0; iCol < bitmap.PixelWidth; iCol++)
                    {
                        currentPixel++;
                        *(pStart + currentPixel * 3 + 0) = lightness.B; //Blue
                        *(pStart + currentPixel * 3 + 1) = lightness.G; //Green
                        *(pStart + currentPixel * 3 + 2) = lightness.R; //red
                    }

                    iRowCurrent -= iRowUnit;
                }

                bitmap.AddDirtyRect(new Int32Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight));
                bitmap.Unlock();
            }
        }
Beispiel #2
0
        internal static bool CopyGdipBitmapToWicBitmap(System.Drawing.Bitmap gdipBitmap, System.Windows.Media.Imaging.WriteableBitmap wicBitmap)
        {
            System.Diagnostics.Debug.Assert(gdipBitmap != null && wicBitmap != null);
            if (wicBitmap.Format != System.Windows.Media.PixelFormats.Pbgra32)
            {
                return(false);
            }
            if (gdipBitmap.PixelFormat != System.Drawing.Imaging.PixelFormat.Format32bppArgb)
            {
                return(false);
            }
            wicBitmap.Lock();
            // GDI+ ビットマップから WIC ビットマップへ転送する際、ウィンドウ矩形やユーザー定義クリッピング矩形を考慮すれば、もっと効率化できる?
            // 単純にそのままごっそりブロック コピーしてしまったほうがむしろ速い?
            var gdipBitmapLockData = gdipBitmap.LockBits(
                new System.Drawing.Rectangle(0, 0, gdipBitmap.Width, gdipBitmap.Height),
                System.Drawing.Imaging.ImageLockMode.ReadOnly,
                gdipBitmap.PixelFormat);

            // GDI+ の PixelFormat と WIC の PixelFormat はメンバーの命名規則が異なるが、
            // どちらも DIB は GDI からの仕様に準じているため、BGRA の順で並んでいる。
            // GDI+ の命名は昔の Direct3D の D3DFMT_A8R8G8B8 に、WIC の命名は DXGI の DXGI_FORMAT_B8G8R8A8_UNORM に近い。
            // ともに 32bit であればパディングも考慮する必要がないので、そのまま高速にブロック コピーできる。
            Kernel32DllMethodsInvoker.CopyMemory(wicBitmap.BackBuffer, gdipBitmapLockData.Scan0,
                                                 new IntPtr(wicBitmap.PixelHeight * wicBitmap.BackBufferStride));
            gdipBitmap.UnlockBits(gdipBitmapLockData);
            wicBitmap.AddDirtyRect(new System.Windows.Int32Rect(0, 0, wicBitmap.PixelWidth, wicBitmap.PixelHeight));
            wicBitmap.Unlock();
            return(true);
        }
Beispiel #3
0
        public override void UpdateColorPlaneBitmap(System.Windows.Media.Imaging.WriteableBitmap bitmap, int normalComponentValue)
        {
            unsafe
            {
                bitmap.Lock();
                byte * pStart       = (byte *)(void *)bitmap.BackBuffer;
                int    currentPixel = -1;
                double iRowUnit     = (double)100 / bitmap.PixelHeight;
                double iColUnit     = (double)1;
                double iRowCurrent  = 100;


                double b = (double)normalComponentValue;
                for (int iRow = 0; iRow < bitmap.PixelHeight; iRow++)
                {
                    double l           = iRowCurrent;
                    double iColCurrent = -128;
                    for (int iCol = 0; iCol < bitmap.PixelWidth; iCol++)
                    {
                        double theta = 6.0 / 29.0;
                        double a     = iColCurrent;
                        double fy    = (l + 16) / 116.0;
                        double fx    = fy + (a / 500.0);
                        double fz    = fy - (b / 200.0);

                        var x = (fx > theta) ? D65X * (fx * fx * fx) : (fx - 16.0 / 116.0) * 3 * (theta * theta) * D65X;
                        var y = (fy > theta) ? D65Y * (fy * fy * fy) : (fy - 16.0 / 116.0) * 3 * (theta * theta) * D65Y;
                        var z = (fz > theta) ? D65Z * (fz * fz * fz) : (fz - 16.0 / 116.0) * 3 * (theta * theta) * D65Z;

                        x = (x > 0.9505) ? 0.9505 : ((x < 0) ? 0 : x);
                        y = (y > 1.0) ? 1.0 : ((y < 0) ? 0 : y);
                        z = (z > 1.089) ? 1.089 : ((z < 0) ? 0 : z);

                        double[] Clinear = new double[3];
                        Clinear[0] = x * 3.2410 - y * 1.5374 - z * 0.4986;  // red
                        Clinear[1] = -x * 0.9692 + y * 1.8760 - z * 0.0416; // green
                        Clinear[2] = x * 0.0556 - y * 0.2040 + z * 1.0570;  // blue

                        for (int i = 0; i < 3; i++)
                        {
                            Clinear[i] = (Clinear[i] <= 0.0031308) ? 12.92 * Clinear[i] : (1 + 0.055) * Math.Pow(Clinear[i], (1.0 / 2.4)) - 0.055;
                            Clinear[i] = Math.Min(Clinear[i], 1);
                            Clinear[i] = Math.Max(Clinear[i], 0);
                        }


                        currentPixel++;
                        *(pStart + currentPixel * 3 + 0) = Convert.ToByte(Clinear[2] * 255); //Blue
                        *(pStart + currentPixel * 3 + 1) = Convert.ToByte(Clinear[1] * 255); //Green
                        *(pStart + currentPixel * 3 + 2) = Convert.ToByte(Clinear[0] * 255); //red
                        iColCurrent += iColUnit;
                    }
                    iRowCurrent -= iRowUnit;
                }
                bitmap.AddDirtyRect(new Int32Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight));
                bitmap.Unlock();
            }
        }
Beispiel #4
0
        public static void SetPixels(WIC_WRITABLE dstBmp, int dstX, int dstY, PointerBitmap srcPtr)
        {
            if (dstX < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(dstX));
            }
            if (dstY < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(dstY));
            }
            if (dstX + srcPtr.Width > dstBmp.PixelWidth)
            {
                throw new ArgumentOutOfRangeException(nameof(srcPtr.Width));
            }
            if (dstY + srcPtr.Height > dstBmp.PixelHeight)
            {
                throw new ArgumentOutOfRangeException(nameof(srcPtr.Height));
            }

            if (!TryGetExactPixelFormat(dstBmp.Format, out var dstFmt))
            {
                throw new Diagnostics.PixelFormatNotSupportedException(dstBmp.Format, nameof(dstBmp));
            }

            if (srcPtr.PixelFormat == dstFmt)
            {
                var rect = new System.Windows.Int32Rect(dstX, dstY, dstBmp.PixelWidth, dstBmp.PixelHeight);

                dstBmp.WritePixels(rect, srcPtr.Pointer, srcPtr.Info.BitmapByteSize, srcPtr.Info.StepByteSize);
                return;
            }

            try
            {
                dstBmp.Lock();

                var nfo    = new BitmapInfo(dstBmp.PixelWidth, dstBmp.PixelHeight, dstFmt, dstBmp.BackBufferStride);
                var dstPtr = new PointerBitmap(dstBmp.BackBuffer, nfo);

                dstPtr.AsSpanBitmap().SetPixels(0, 0, srcPtr.AsSpanBitmap());

                var w     = Math.Min(dstBmp.PixelWidth, srcPtr.Width);
                var h     = Math.Min(dstBmp.PixelHeight, srcPtr.Height);
                var drect = new System.Windows.Int32Rect(0, 0, w, h);

                dstBmp.AddDirtyRect(drect);
            }
            finally
            {
                dstBmp.Unlock();
            }
        }
Beispiel #5
0
        /// <summary>
        /// Draws simple rect. Note! First lock wbitmap, and unlock after using this f-tion
        /// </summary>
        /// <param name="writeableBitmap">source wbitmap</param>
        /// <param name="left">X</param>
        /// <param name="top">Y</param>
        /// <param name="width">Width</param>
        /// <param name="height">Height</param>
        /// <param name="color">Color of rect</param>
        public static void DrawRectangle(System.Windows.Media.Imaging.WriteableBitmap writeableBitmap, int left, int top, int width, int height, Color color)
        {
            // Compute the pixel's color
            int colorData = color.R << 16; // R

            colorData |= color.G << 8;     // G
            colorData |= color.B << 0;     // B
            int bpp = writeableBitmap.Format.BitsPerPixel / 8;

            unsafe
            {
                for (int y = 0; y < height; y++)
                {
                    // Get a pointer to the back buffer
                    var pBackBuffer = (int)writeableBitmap.BackBuffer;

                    // Find the address of the pixel to draw
                    pBackBuffer += (top + y) * writeableBitmap.BackBufferStride;
                    pBackBuffer += left * bpp;
                    int step;

                    if (y == 0 || y == height - 1)
                    {
                        step = 1;
                    }
                    else
                    {
                        step = width - 1;
                    }

                    for (int x = 0; x < width; x += step)
                    {
                        // Assign the color data to the pixel
                        *((int *)pBackBuffer) = colorData;

                        // Increment the address of the pixel to draw
                        pBackBuffer += bpp * step;
                    }
                }
            }

            try
            {
                writeableBitmap.AddDirtyRect(new Int32Rect(left, top, width, height));
            }
            catch (Exception e)
            {
            }
        }