/// <summary>
 /// Resize to square image
 /// </summary>
 /// <param name="stream"></param>
 /// <param name="targetSize"></param>
 /// <param name="format"></param>
 /// <param name="alphaMode"></param>
 /// <returns></returns>
 public static Task <SoftwareBitmap> ResizeImageToSquareAsync(IRandomAccessStream stream,
                                                              int targetSize,
                                                              BitmapPixelFormat format  = BitmapPixelFormat.Unknown,
                                                              BitmapAlphaMode alphaMode = BitmapAlphaMode.Ignore)
 {
     return(ResizeImageAsync(stream, targetSize, targetSize));
 }
Beispiel #2
0
        bool IsFormatSupportedByWin2D(BitmapPixelFormat format, BitmapAlphaMode alphaMode)
        {
            // Win2D only supports A8UintNormalized with straight alpha.  SoftwareBitmap doesn't
            // support A8UintNormalized.
            if (alphaMode == BitmapAlphaMode.Straight)
            {
                return(false);
            }

            switch (format)
            {
            case BitmapPixelFormat.Gray16:
            case BitmapPixelFormat.Nv12:
            case BitmapPixelFormat.Yuy2:
                // Direct2D doesn't support these formats
                return(false);

            case BitmapPixelFormat.Gray8:
                if (alphaMode == BitmapAlphaMode.Ignore)
                {
                    return(false);
                }
                else
                {
                    return(true);
                }
            }

            return(true);
        }
Beispiel #3
0
        private async Task ResizeToJpegPhoto(IRandomAccessStream inputStream, IRandomAccessStream outputStream, uint maxSize)
        {
            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(inputStream);

            double scaleFactor = 1.0;
            uint   pixelSize   = decoder.PixelWidth > decoder.PixelHeight ? decoder.PixelWidth : decoder.PixelHeight;

            if (pixelSize > maxSize)
            {
                scaleFactor = (double)maxSize / pixelSize;
            }
            BitmapTransform transform = new BitmapTransform();

            transform.ScaledWidth       = (uint)(decoder.PixelWidth * scaleFactor);
            transform.ScaledHeight      = (uint)(decoder.PixelHeight * scaleFactor);
            transform.InterpolationMode = BitmapInterpolationMode.Fant;

            BitmapPixelFormat pixelFormat       = decoder.BitmapPixelFormat;
            BitmapAlphaMode   alphaMode         = decoder.BitmapAlphaMode;
            PixelDataProvider pixelDataProvider = await decoder.GetPixelDataAsync(pixelFormat, alphaMode, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage);

            var pixels = pixelDataProvider.DetachPixelData();

            uint finalWidth  = (uint)(decoder.OrientedPixelWidth * scaleFactor);
            uint finalHeight = (uint)(decoder.OrientedPixelHeight * scaleFactor);

            BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, outputStream);

            encoder.SetPixelData(pixelFormat, alphaMode, finalWidth, finalHeight, decoder.DpiX, decoder.DpiY, pixels);
            await encoder.FlushAsync();
        }
Beispiel #4
0
 /// <summary>
 /// Clients should override this method if the post-processing can be
 /// done in place.
 ///
 /// <para />The provided bitmap is a copy of the source bitmap and the
 /// implementation is free to modify it.
 /// </summary>
 /// <param name="data">The bitmap pixel data.</param>
 /// <param name="width">
 /// The width of the new software bitmap, in pixels.
 /// </param>
 /// <param name="height">
 /// The height of the new software bitmap, in pixels.
 /// </param>
 /// <param name="format">
 /// The pixel format of the new software bitmap.
 /// </param>
 /// <param name="alpha">
 /// The alpha mode of the new software bitmap.
 /// </param>
 public virtual void Process(
     byte[] data,
     int width,
     int height,
     BitmapPixelFormat format,
     BitmapAlphaMode alpha)
 {
 }
 /// <summary>
 /// Clients should override this method if the post-processing can be
 /// done in place.
 ///
 /// <para />The provided bitmap is a copy of the source bitmap and the
 /// implementation is free to modify it.
 /// </summary>
 /// <param name="data">The bitmap pixel data.</param>
 /// <param name="width">
 /// The width of the new software bitmap, in pixels.
 /// </param>
 /// <param name="height">
 /// The height of the new software bitmap, in pixels.
 /// </param>
 /// <param name="format">
 /// The pixel format of the new software bitmap.
 /// </param>
 /// <param name="alpha">
 /// The alpha mode of the new software bitmap.
 /// </param>
 public override void Process(
     byte[] data,
     int width,
     int height,
     BitmapPixelFormat format,
     BitmapAlphaMode alpha)
 {
     _processFunc(data, width, height, format, alpha);
 }
Beispiel #6
0
        /// <summary>
        /// captures and saves the 15:9 image with rotation and cropping applied
        /// </summary>
        private async void CaptureFifteenByNineImage()
        {
            //declare string for filename
            string captureFileName = string.Empty;
            //declare image format
            ImageEncodingProperties format = ImageEncodingProperties.CreateJpeg();

            using (var imageStream = new InMemoryRandomAccessStream()) {
                //generate stream from MediaCapture
                await _captureManager.CapturePhotoToStreamAsync(format, imageStream);

                //create decoder and transform
                BitmapDecoder dec = await BitmapDecoder.CreateAsync(imageStream);

                BitmapTransform transform = new BitmapTransform();

                //roate the image
                transform.Rotation = BitmapRotation.Clockwise90Degrees;
                transform.Bounds   = GetBounds();

                //get the conversion data that we need to save the cropped and rotated image
                BitmapPixelFormat pixelFormat = dec.BitmapPixelFormat;
                BitmapAlphaMode   alpha       = dec.BitmapAlphaMode;

                //read the PixelData
                PixelDataProvider pixelProvider = await dec.GetPixelDataAsync(
                    pixelFormat,
                    alpha,
                    transform,
                    ExifOrientationMode.RespectExifOrientation,
                    ColorManagementMode.ColorManageToSRgb
                    );

                byte[] pixels = pixelProvider.DetachPixelData();

                if (PhotoTaked != null)
                {
                    PhotoTaked(this, new PhotoTakedEventArgs(pixels));
                }

                Frame rootFrame = Window.Current.Content as Frame;

                if (rootFrame != null && rootFrame.CanGoBack)
                {
                    rootFrame.GoBack();
                }
            }

            CleanCapture();
        }
Beispiel #7
0
        void TestCreateFromSoftwareBitmap(BitmapPixelFormat pixelFormat, BitmapAlphaMode alphaMode)
        {
            if (pixelFormat == BitmapPixelFormat.Unknown)
            {
                return;
            }

            int anyWidth  = 3;
            int anyHeight = 5;

            var softwareBitmap = new SoftwareBitmap(pixelFormat, anyWidth, anyHeight, alphaMode);

            if (!IsFormatSupportedByWin2D(pixelFormat, alphaMode))
            {
                Assert.ThrowsException <Exception>(() =>
                {
                    CanvasBitmap.CreateFromSoftwareBitmap(device, softwareBitmap);
                });
                return;
            }

            var canvasBitmap = CanvasBitmap.CreateFromSoftwareBitmap(device, softwareBitmap);

            Assert.AreEqual(anyWidth, (int)canvasBitmap.SizeInPixels.Width);
            Assert.AreEqual(anyHeight, (int)canvasBitmap.SizeInPixels.Height);
            Assert.AreEqual(GetDirectXPixelFormatUsedForBitmapPixelFormat(pixelFormat), canvasBitmap.Format);

            CanvasAlphaMode expectedAlphaMode = CanvasAlphaMode.Straight;

            switch (alphaMode)
            {
            case BitmapAlphaMode.Ignore: expectedAlphaMode = CanvasAlphaMode.Ignore; break;

            case BitmapAlphaMode.Premultiplied: expectedAlphaMode = CanvasAlphaMode.Premultiplied; break;

            case BitmapAlphaMode.Straight: expectedAlphaMode = CanvasAlphaMode.Straight; break;
            }

            Assert.AreEqual(expectedAlphaMode, canvasBitmap.AlphaMode);
        }
        private void InvertPostprocessor(
            byte[] data,
            int width,
            int height,
            BitmapPixelFormat format,
            BitmapAlphaMode alpha)
        {
            byte value  = 255;
            var  stride = 4 * width;

            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    int k = stride * i + 4 * j;
                    data[k + 0] = (byte)(value - data[k]);
                    data[k + 1] = (byte)(value - data[k + 1]);
                    data[k + 2] = (byte)(value - data[k + 2]);
                    data[k + 3] = 255;
                }
            }
        }
        private void GrayscalePostprocessor(
            byte[] data,
            int width,
            int height,
            BitmapPixelFormat format,
            BitmapAlphaMode alpha)
        {
            var stride = 4 * width;

            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    int k         = stride * i + 4 * j;
                    int grayScale = (int)((data[k + 2] * 0.3) + (data[k + 1] * 0.59) + (data[k] * 0.11));
                    data[k]     = (byte)grayScale;
                    data[k + 1] = (byte)grayScale;
                    data[k + 2] = (byte)grayScale;
                    data[k + 3] = 255;
                }
            }
        }
Beispiel #10
0
        public async static Task SaveImageAsync(BitmapSource image, IRandomAccessStream file)
        {
            BitmapEncoder encoder = await BitmapEncoder.CreateAsync(Windows.Graphics.Imaging.BitmapEncoder.PngEncoderId, file);

            WriteableBitmap writeable = image as WriteableBitmap;

            if (writeable == null)
            {
                return;
            }

            // remember the format of this image
            BitmapPixelFormat format = PixelBufferObject.GetBitmapPixelFormat(writeable);
            BitmapAlphaMode   mode   = PixelBufferObject.GetBitmapAlphaMode(writeable);

            IBuffer    buffer     = writeable.PixelBuffer;
            DataReader dataReader = DataReader.FromBuffer(buffer);

            byte[] pixels = new byte[buffer.Length];
            dataReader.ReadBytes(pixels);

            encoder.SetPixelData(format, mode, (uint)image.PixelWidth, (uint)image.PixelHeight, 96, 96, pixels);
            await encoder.FlushAsync();
        }
Beispiel #11
0
        void TestCreateFromSoftwareBitmap(CanvasDevice device, BitmapPixelFormat pixelFormat, BitmapAlphaMode alphaMode)
        {
            if (pixelFormat == BitmapPixelFormat.Unknown)
                return;

            int anyWidth = 3;
            int anyHeight = 5;

            var softwareBitmap = new SoftwareBitmap(pixelFormat, anyWidth, anyHeight, alphaMode);

            if (!IsFormatSupportedByWin2D(pixelFormat, alphaMode))
            {
                Assert.ThrowsException<Exception>(() =>
                {
                    CanvasBitmap.CreateFromSoftwareBitmap(device, softwareBitmap);
                });
                return;
            }
            
            var canvasBitmap = CanvasBitmap.CreateFromSoftwareBitmap(device, softwareBitmap);

            Assert.AreEqual(anyWidth, (int)canvasBitmap.SizeInPixels.Width);
            Assert.AreEqual(anyHeight, (int)canvasBitmap.SizeInPixels.Height);
            Assert.AreEqual(GetDirectXPixelFormatUsedForBitmapPixelFormat(pixelFormat), canvasBitmap.Format);

            CanvasAlphaMode expectedAlphaMode = CanvasAlphaMode.Straight;
            switch (alphaMode)
            {
                case BitmapAlphaMode.Ignore: expectedAlphaMode = CanvasAlphaMode.Ignore; break;
                case BitmapAlphaMode.Premultiplied: expectedAlphaMode = CanvasAlphaMode.Premultiplied; break;
                case BitmapAlphaMode.Straight: expectedAlphaMode = CanvasAlphaMode.Straight; break;
            }

            Assert.AreEqual(expectedAlphaMode, canvasBitmap.AlphaMode);
        }
Beispiel #12
0
        /// <summary>
        /// 处理并保存图片
        /// </summary>
        /// <param name="inputFile">输入文件</param>
        /// <param name="outputFile">输出文件</param>
        /// <param name="longSide">长边长度</param>
        /// <returns>成功返回true,否则false。</returns>
        private async Task <bool> LoadSaveFileAsync(StorageFile inputFile, StorageFile outputFile, uint longSide)
        {
            try
            {
                Guid encoderId;
                switch (outputFile.FileType)
                {
                case ".png":
                    encoderId = BitmapEncoder.PngEncoderId;
                    break;

                case ".bmp":
                    encoderId = BitmapEncoder.BmpEncoderId;
                    break;

                case ".jpg":
                case ".jpeg":
                default:
                    encoderId = BitmapEncoder.JpegEncoderId;
                    break;
                }

                //图片处理部分
                using (IRandomAccessStream inputStream = await inputFile.OpenAsync(FileAccessMode.Read),
                       outputStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
                {
                    //BitmapEncoder需要一个空的输出流; 但是用户可能已经选择了预先存在的文件,所以清零。
                    outputStream.Size = 0;

                    //从解码器获取像素数据。 我们对解码的像素应用用户请求的变换以利用解码器中的潜在优化。
                    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(inputStream);

                    BitmapTransform transform = new BitmapTransform();

                    //原图尺寸比转换尺寸更小
                    if (decoder.PixelHeight < longSide && decoder.PixelWidth < longSide)
                    {
                        throw new Exception("设置的尺寸大于原图尺寸!");
                    }
                    // 判断长边并按原图比例确定另一条边的长度
                    if (decoder.PixelHeight > decoder.PixelWidth)
                    {
                        transform.ScaledHeight = longSide;
                        transform.ScaledWidth  = (uint)(decoder.PixelWidth * ((float)longSide / decoder.PixelHeight));
                    }
                    else
                    {
                        transform.ScaledHeight = (uint)(decoder.PixelHeight * ((float)longSide / decoder.PixelWidth));
                        transform.ScaledWidth  = longSide;
                    }

                    // Fant是相对高质量的插值模式。
                    transform.InterpolationMode = BitmapInterpolationMode.Fant;

                    // BitmapDecoder指示最佳匹配本地存储的图像数据的像素格式和alpha模式。 这可以提供高性能的与或质量增益。
                    BitmapPixelFormat format = decoder.BitmapPixelFormat;
                    BitmapAlphaMode   alpha  = decoder.BitmapAlphaMode;

                    // PixelDataProvider提供对位图帧中像素数据的访问
                    PixelDataProvider pixelProvider = await decoder.GetPixelDataAsync(
                        format,
                        alpha,
                        transform,
                        ExifOrientationMode.RespectExifOrientation,
                        ColorManagementMode.ColorManageToSRgb
                        );

                    byte[] pixels = pixelProvider.DetachPixelData();

                    //将像素数据写入编码器。
                    BitmapEncoder encoder = await BitmapEncoder.CreateAsync(encoderId, outputStream);

                    //设置像素数据
                    encoder.SetPixelData(
                        format,
                        alpha,
                        transform.ScaledWidth,
                        transform.ScaledHeight,
                        decoder.DpiX,
                        decoder.DpiY,
                        pixels
                        );

                    await encoder.FlushAsync(); //异步提交和刷新所有图像数据(这一步保存图片到文件)

                    Debug.WriteLine("保存成功:" + outputFile.Path);

                    // 显示图片
                    BitmapImage src = new BitmapImage();
                    //    IRandomAccessStream stream = await outputFile.OpenAsync(FileAccessMode.Read);
                    //从解码器获取像素数据。 我们对解码的像素应用用户请求的变换以利用解码器中的潜在优化。
                    BitmapDecoder decoder0 = await BitmapDecoder.CreateAsync(outputStream);

                    Compress_Size_info.Text = "压缩尺寸:" + decoder0.PixelHeight.ToString() + "*" + decoder0.OrientedPixelWidth.ToString();

                    string[] units       = new String[] { "B", "KB", "MB", "GB", "TB" };
                    int      digitGroups = (int)(Math.Log10(outputStream.Size) / Math.Log10(1024));
                    Compress_Save.Text = "压缩大小:" + String.Format("{0:F}", (outputStream.Size / Math.Pow(1024, digitGroups))) + " " + units[digitGroups];
                    //总压缩字节数
                    Compress_byte = outputStream.Size;

                    await src.SetSourceAsync(outputStream);

                    Compress_Image.Source = src;

                    //压缩总结
                    Now_save();
                    Total_save();

                    return(true);
                }
            }
            catch (Exception err)
            {
                Debug.WriteLine(err.Message);
                return(false);
            }
        }
Beispiel #13
0
        public static async Task CropandScaleAsync(StorageFile source, StorageFile dest, Point startPoint, Size size, double m_scaleFactor)
        {
            uint startPointX = (uint)Math.Floor(startPoint.X);
            uint startPointY = (uint)Math.Floor(startPoint.Y);
            uint height      = (uint)Math.Floor(size.Height);
            uint width       = (uint)Math.Floor(size.Width);

            using (IRandomAccessStream sourceStream = await source.OpenReadAsync(),
                   destStream = await dest.OpenAsync(FileAccessMode.ReadWrite))
            {
                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(sourceStream);

                var m_displayHeightNonScaled = decoder.OrientedPixelHeight;
                var m_displayWidthNonScaled  = decoder.OrientedPixelWidth;

                // Use the native (no orientation applied) image dimensions because we want to handle
                // orientation ourselves.
                BitmapTransform transform = new BitmapTransform();
                BitmapBounds    bounds    = new BitmapBounds()
                {
                    X      = (uint)(startPointX * m_scaleFactor),
                    Y      = (uint)(startPointY * m_scaleFactor),
                    Height = (uint)(height * m_scaleFactor),
                    Width  = (uint)(width * m_scaleFactor)
                };
                transform.Bounds = bounds;

                // Scaling occurs before flip/rotation, therefore use the original dimensions
                // (no orientation applied) as parameters for scaling.
                transform.ScaledHeight = (uint)(decoder.PixelHeight * m_scaleFactor);
                transform.ScaledWidth  = (uint)(decoder.PixelWidth * m_scaleFactor);
                transform.Rotation     = BitmapRotation.None;

                // Fant is a relatively high quality interpolation mode.
                transform.InterpolationMode = BitmapInterpolationMode.Fant;
                BitmapPixelFormat format = decoder.BitmapPixelFormat;
                BitmapAlphaMode   alpha  = decoder.BitmapAlphaMode;

                // Set the encoder's destination to the temporary, in-memory stream.
                PixelDataProvider pixelProvider = await decoder.GetPixelDataAsync(
                    format,
                    alpha,
                    transform,
                    ExifOrientationMode.IgnoreExifOrientation,
                    ColorManagementMode.ColorManageToSRgb
                    );

                byte[] pixels = pixelProvider.DetachPixelData();


                Guid encoderID = Guid.Empty;

                switch (dest.FileType.ToLower())
                {
                case ".png":
                    encoderID = BitmapEncoder.PngEncoderId;
                    break;

                case ".bmp":
                    encoderID = BitmapEncoder.BmpEncoderId;
                    break;

                default:
                    encoderID = BitmapEncoder.JpegEncoderId;
                    break;
                }

                // Write the pixel data onto the encoder. Note that we can't simply use the
                // BitmapTransform.ScaledWidth and ScaledHeight members as the user may have
                // requested a rotation (which is applied after scaling).
                var encoder = await BitmapEncoder.CreateAsync(encoderID, destStream);

                encoder.SetPixelData(
                    format,
                    alpha,
                    (bounds.Width),
                    (bounds.Height),
                    decoder.DpiX,
                    decoder.DpiY,
                    pixels
                    );

                await encoder.FlushAsync();
            }
        }
        /// <summary>
        /// Resize image with format
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="targetWidth"></param>
        /// <param name="targetHeight"></param>
        /// <param name="format"></param>
        /// <param name="alphaMode"></param>
        /// <returns></returns>
        public static async Task <SoftwareBitmap> ResizeImageAsync(IRandomAccessStream stream,
                                                                   int targetWidth,
                                                                   int targetHeight,
                                                                   BitmapPixelFormat format  = BitmapPixelFormat.Unknown,
                                                                   BitmapAlphaMode alphaMode = BitmapAlphaMode.Ignore)
        {
            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);

            var originalPixelWidth  = decoder.PixelWidth;
            var originalPixelHeight = decoder.PixelHeight;

            using (var outputStream = new InMemoryRandomAccessStream())
            {
                //create encoder based on decoder of the source file
                var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);

                double widthRatio = (double)targetWidth / originalPixelWidth;
                double heightRatio = (double)targetHeight / originalPixelHeight;
                uint   aspectHeight = (uint)targetHeight;
                uint   aspectWidth = (uint)targetWidth;
                uint   cropX = 0, cropY = 0;
                var    scaledWith   = (uint)targetWidth;
                var    scaledHeight = (uint)targetHeight;
                if (originalPixelWidth > originalPixelHeight)
                {
                    aspectWidth = (uint)(heightRatio * originalPixelWidth);
                    cropX       = (aspectWidth - aspectHeight) / 2;
                }
                else
                {
                    aspectHeight = (uint)(widthRatio * originalPixelHeight);
                    cropY        = (aspectHeight - aspectWidth) / 2;
                }
                //you can adjust interpolation and other options here, so far linear is fine for thumbnails
                encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Linear;
                encoder.BitmapTransform.ScaledHeight      = aspectHeight;
                encoder.BitmapTransform.ScaledWidth       = aspectWidth;
                encoder.BitmapTransform.Bounds            = new BitmapBounds()
                {
                    Width  = scaledWith,
                    Height = scaledHeight,
                    X      = cropX,
                    Y      = cropY,
                };
                await encoder.FlushAsync();

                //get reszied image
                var outputDecoder = await BitmapDecoder.CreateAsync(outputStream);

                var outputImg = await outputDecoder.GetSoftwareBitmapAsync();

                // apply alpha mode
                outputImg = SoftwareBitmap.Convert(outputImg, outputImg.BitmapPixelFormat, alphaMode);
                //apply piexl format
                if (format != BitmapPixelFormat.Unknown && format != decoder.BitmapPixelFormat)
                {
                    return(SoftwareBitmap.Convert(outputImg, format));
                }
                return(outputImg);
            }
        }
        public async Task SetPixel(byte[,] r_color, byte[,] g_color, byte[,] b_color, string file_name, byte simplifier)
        {
            // saving to variables resolution of the image
            int width  = r_color.GetLength(0);
            int height = r_color.GetLength(1);

            // simplify colors by dividing without remainder and then multipling by simplifier
            {
                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        b_color[i, j]  = Convert.ToByte(b_color[i, j] / simplifier);
                        b_color[i, j] *= simplifier;
                        g_color[i, j]  = Convert.ToByte(g_color[i, j] / simplifier);
                        g_color[i, j] *= simplifier;
                        r_color[i, j]  = Convert.ToByte(r_color[i, j] / simplifier);
                        r_color[i, j] *= simplifier;
                    }
                }
                byte  t             = 192;
                sbyte border        = 2; // distance from the central pixel to border of checking mask
                byte  threshold     = 55;
                bool  is_background = false;

                // setting up background detecting for each simplifier in the program
                if (simplifier == 85)
                {
                    t = 170;
                }
                else if (simplifier == 64)
                {
                    t = 192;
                }
                else
                {
                    t = 204;
                }

                // algorithm has a deadzone - protection from getting out of array
                for (int i = border; i < width - border; i = i + border + 1)
                {
                    for (int j = border; j < height - border; j = j + border + 1)
                    {
                        uint goodpixel_counter = 0, badpixel_counter = 0;

                        // checking if pixel is background-pixel
                        if (r_color[i, j] == t && g_color[i, j] == t && b_color[i, j] == t)
                        {
                            is_background = true;
                        }
                        else
                        {
                            is_background = false;
                        }

                        // if pixel is not background-pixel, the algorithm executes cross-checking in 8 directions
                        // and counts how many positive scores there are - above setpoint
                        // if there is pixels above setpoint, then every neighbor pixel takes value of center pixel
                        if (is_background == false)
                        {
                            for (int n = (-border); n <= border; n++)
                            {
                                if (n == 0)
                                {
                                    continue;
                                }
                                if (r_color[i + n, j + n] == r_color[i, j] && g_color[i + n, j + n] == g_color[i, j] && b_color[i + n, j + n] == b_color[i, j])
                                {
                                    goodpixel_counter++;
                                }
                                else
                                {
                                    badpixel_counter++;
                                }

                                if (r_color[i + n, j - n] == r_color[i, j] && g_color[i + n, j - n] == g_color[i, j] && b_color[i + n, j - n] == b_color[i, j])
                                {
                                    goodpixel_counter++;
                                }
                                else
                                {
                                    badpixel_counter++;
                                }

                                if (r_color[i + n, j + 0] == r_color[i, j] && g_color[i + n, j + 0] == g_color[i, j] && b_color[i + n, j + 0] == b_color[i, j])
                                {
                                    goodpixel_counter++;
                                }
                                else
                                {
                                    badpixel_counter++;
                                }

                                if (r_color[i + n, j + n] == r_color[i, j] && g_color[i + n, j + n] == g_color[i, j] && b_color[i + n, j + n] == b_color[i, j])
                                {
                                    goodpixel_counter++;
                                }
                                else
                                {
                                    badpixel_counter++;
                                }
                            }
                            if (100 * goodpixel_counter / (badpixel_counter + goodpixel_counter) > threshold)
                            {
                                for (int x = -(border); x <= border; x++)
                                {
                                    for (int y = -(border); y <= border; y++)
                                    {
                                        if (x == 0 & y == 0)
                                        {
                                            continue;
                                        }
                                        r_color[i + x, j + y] = r_color[i, j];
                                        g_color[i + x, j + y] = g_color[i, j];
                                        b_color[i + x, j + y] = b_color[i, j];
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // WriteableBitmap uses BGRA format - 4 bytes per pixel
            byte[] image_array = new byte[width * height * 4];

            BitmapAlphaMode alpha_mode = BitmapAlphaMode.Ignore;

            // saving to byte array the 2D color arrays
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    image_array[4 * ((width * j) + i) + 0] = b_color[i, j]; // blue
                    image_array[4 * ((width * j) + i) + 1] = g_color[i, j]; // green
                    image_array[4 * ((width * j) + i) + 2] = r_color[i, j]; // red
                }
            }

            // saving data to file with sent image settings (parameters)
            await SaveToFile(image_array, file_name, CreationCollisionOption.ReplaceExisting, BitmapPixelFormat.Bgra8, alpha_mode);
        }
        public async Task <StorageFile> SaveToFile(byte[] image_array, string file_name, CreationCollisionOption collision, BitmapPixelFormat image_format, BitmapAlphaMode alpha_mode)
        {
            //  create new bitmap
            WriteableBitmap image = new WriteableBitmap(ImageWidth, ImageHeight);

            // 'using' ensures that the data stream will be disposed after operation is finished
            using (Stream image_stream = image.PixelBuffer.AsStream())
            {
                await image_stream.WriteAsync(image_array, 0, ImageHeight *ImageWidth * 4);
            }

            // create new file in 'Pictures' folder with sent name and collision setting
            var file = await KnownFolders.PicturesLibrary.CreateFileAsync(file_name, collision);

            // opening file by data stream
            using (IRandomAccessStream image_stream = await file.OpenAsync(FileAccessMode.ReadWrite))
            {
                // encoding image from created data stream
                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, image_stream);

                Stream pixel_stream = image.PixelBuffer.AsStream();

                // creating an array with data stream's length
                byte[] pixel_array = new byte[pixel_stream.Length];

                // reading the data
                await pixel_stream.ReadAsync(pixel_array, 0, pixel_array.Length);

                // encoding the image with parameters below:
                encoder.SetPixelData(image_format, alpha_mode, // format and alpha channel
                                     (uint)image.PixelWidth,   // image width
                                     (uint)image.PixelHeight,  // image height
                                     96.0,                     // DPI in width
                                     96.0,                     // DPI in height
                                     pixel_array);             // byte stream
                await encoder.FlushAsync();                    // end of encoding
            }
            return(file);                                      // returning file
        }
Beispiel #17
0
        /// <summary>
        /// 图片压缩
        /// (目前好像还有些问题)
        /// </summary>
        /// <param name="imageStream">图片流</param>
        /// <param name="fileType">文件后缀</param>
        /// <param name="maxWidth">最大宽度</param>
        /// <param name="maxHeight">最大高度</param>
        /// <returns></returns>
        public static async Task <IRandomAccessStream> ImageCompressAsync(IRandomAccessStream imageStream, string fileType, uint maxWidth, uint maxHeight)
        {
            IRandomAccessStream result = null;

            try
            {
                result = new InMemoryRandomAccessStream();

                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(imageStream);

                //判断是否需要压缩图片
                if (decoder.PixelWidth > maxWidth || decoder.PixelHeight > maxHeight || imageStream.Size > 2097152)
                {
                    BitmapTransform transform = new BitmapTransform();
                    Guid            encoderId;
                    switch (fileType)
                    {
                    case ".png":
                        encoderId = BitmapEncoder.PngEncoderId;
                        break;

                    case ".bmp":
                        encoderId = BitmapEncoder.BmpEncoderId;
                        break;

                    case ".jpg":
                    default:
                        encoderId = BitmapEncoder.JpegEncoderId;
                        break;
                    }

                    //设置缩放大小
                    if (decoder.OrientedPixelWidth / maxWidth > decoder.OrientedPixelHeight / maxHeight)    //按宽度缩放
                    {
                        double scale = maxWidth * 1.0 / decoder.OrientedPixelWidth;
                        transform.ScaledHeight = (uint)(decoder.OrientedPixelHeight * scale);
                        transform.ScaledWidth  = (uint)(decoder.OrientedPixelWidth * scale);
                    }
                    else    //按高度缩放
                    {
                        double scale = maxHeight * 1.0 / decoder.OrientedPixelHeight;
                        transform.ScaledHeight = (uint)(decoder.OrientedPixelHeight * scale);
                        transform.ScaledWidth  = (uint)(decoder.OrientedPixelWidth * scale);
                    }

                    #region 如果不这样做,可能会缩放出错?

                    var width  = transform.ScaledWidth;
                    var height = transform.ScaledHeight;

                    if (decoder.OrientedPixelWidth != decoder.PixelWidth)
                    {
                        width  = transform.ScaledHeight;
                        height = transform.ScaledWidth;
                    }

                    #endregion 如果不这样做,可能会缩放出错?

                    // Fant是相对高质量的插值模式。
                    transform.InterpolationMode = BitmapInterpolationMode.Fant;

                    // BitmapDecoder指示最佳匹配本地存储的图像数据的像素格式和alpha模式。 这可以提供高性能的与或质量增益。
                    BitmapPixelFormat format = decoder.BitmapPixelFormat;
                    BitmapAlphaMode   alpha  = decoder.BitmapAlphaMode;

                    // PixelDataProvider提供对位图帧中像素数据的访问
                    PixelDataProvider pixelProvider = await decoder.GetPixelDataAsync(
                        format,
                        alpha,
                        transform,
                        ExifOrientationMode.RespectExifOrientation,
                        ColorManagementMode.ColorManageToSRgb
                        );

                    byte[] pixels = pixelProvider.DetachPixelData();

                    //将像素数据写入编码器。
                    BitmapEncoder encoder = await BitmapEncoder.CreateAsync(encoderId, result);

                    //设置像素数据
                    encoder.SetPixelData(
                        format,
                        alpha,
                        width,
                        height,
                        decoder.DpiX,
                        decoder.DpiY,
                        pixels
                        );

                    await encoder.FlushAsync(); //异步提交和刷新所有图像数据(这一步保存图片到文件)
                }
                else                            //不需要缩放
                {
                    result = imageStream;
                }
            }
            catch (Exception ex)
            {
                result = null;
                Debug.WriteLine(ex);
            }

            return(result);
        }
Beispiel #18
0
        bool IsFormatSupportedByWin2D(BitmapPixelFormat format, BitmapAlphaMode alphaMode)
        {
            // Win2D only supports A8UintNormalized with straight alpha.  SoftwareBitmap doesn't
            // support A8UintNormalized.
            if (alphaMode == BitmapAlphaMode.Straight)
                return false;

            switch (format)
            {
                case BitmapPixelFormat.Gray16:
                case BitmapPixelFormat.Nv12:
                case BitmapPixelFormat.Yuy2:
                    // Direct2D doesn't support these formats
                    return false;

                case BitmapPixelFormat.Gray8:
                    if (alphaMode == BitmapAlphaMode.Ignore)
                        return false;
                    else
                        return true;
            }

            return true;
        }
Beispiel #19
0
        public static async Task <bool> ImageFileCompression(StorageFile inputFile, StorageFile outputFile, uint longSide)
        {
            try
            {
                Guid encoderId;
                switch (outputFile.FileType)
                {
                case ".png":
                    encoderId = BitmapEncoder.PngEncoderId;
                    break;

                case ".bmp":
                    encoderId = BitmapEncoder.BmpEncoderId;
                    break;

                case ".gif":
                    encoderId = BitmapEncoder.GifEncoderId;
                    break;

                case ".tif":
                case ".tiff":
                    encoderId = BitmapEncoder.TiffEncoderId;
                    break;

                case ".jpg":
                case ".jpeg":
                default:
                    encoderId = BitmapEncoder.JpegEncoderId;
                    break;
                }

                //图片处理部分
                using (IRandomAccessStream inputStream = await inputFile.OpenAsync(FileAccessMode.Read),
                       outputStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
                {
                    //BitmapEncoder需要一个空的输出流; 但是用户可能已经选择了预先存在的文件,所以清零。
                    outputStream.Size = 0;

                    //从解码器获取像素数据。 我们对解码的像素应用用户请求的变换以利用解码器中的潜在优化。
                    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(inputStream);

                    BitmapTransform transform = new BitmapTransform();

                    //原图尺寸比转换尺寸更小
                    if (decoder.PixelHeight < longSide && decoder.PixelWidth < longSide)
                    {
                        //throw new Exception("设置的尺寸大于原图尺寸!");
                        if (decoder.PixelHeight > decoder.PixelWidth)
                        {
                            longSide = decoder.PixelWidth;
                        }
                        else
                        {
                            longSide = decoder.PixelHeight;
                        }
                    }

                    // 判断长边并按原图比例确定另一条边的长度
                    if (decoder.PixelHeight > decoder.PixelWidth)
                    {
                        transform.ScaledHeight = longSide;
                        transform.ScaledWidth  = (uint)(decoder.PixelWidth * ((float)longSide / decoder.PixelHeight));
                    }
                    else
                    {
                        transform.ScaledHeight = (uint)(decoder.PixelHeight * ((float)longSide / decoder.PixelWidth));
                        transform.ScaledWidth  = longSide;
                    }

                    // Fant是相对高质量的插值模式。
                    transform.InterpolationMode = BitmapInterpolationMode.Fant;

                    // BitmapDecoder指示最佳匹配本地存储的图像数据的像素格式和alpha模式。 这可以提供高性能的与或质量增益。
                    BitmapPixelFormat format = decoder.BitmapPixelFormat;
                    BitmapAlphaMode   alpha  = decoder.BitmapAlphaMode;

                    // PixelDataProvider提供对位图帧中像素数据的访问
                    PixelDataProvider pixelProvider = await decoder.GetPixelDataAsync(
                        format,
                        alpha,
                        transform,
                        ExifOrientationMode.RespectExifOrientation,
                        ColorManagementMode.ColorManageToSRgb
                        );

                    byte[] pixels = pixelProvider.DetachPixelData();

                    //将像素数据写入编码器。
                    BitmapEncoder encoder = await BitmapEncoder.CreateAsync(encoderId, outputStream);

                    //设置像素数据
                    encoder.SetPixelData(
                        format,
                        alpha,
                        transform.ScaledWidth,
                        transform.ScaledHeight,
                        decoder.DpiX,
                        decoder.DpiY,
                        pixels
                        );

                    await encoder.FlushAsync(); //异步提交和刷新所有图像数据(这一步保存图片到文件)

                    Console.WriteLine("保存成功:" + outputFile.Path);
                    return(true);
                }
            }
            catch (Exception err)
            {
                Console.WriteLine(err.Message);
                return(false);
            }
        }
Beispiel #20
0
 public static void SetBitmapAlphaMode(DependencyObject obj, BitmapAlphaMode value)
 {
     obj.SetValue(BitmapAlphaModeProperty, value);
 }
Beispiel #21
0
        /// <summary>
        /// captures and saves the 15:9 image with rotation and cropping applied
        /// </summary>
        private async void CaptureFifteenByNineImage()
        {
            //declare string for filename
            string captureFileName = string.Empty;
            //declare image format
            ImageEncodingProperties format = ImageEncodingProperties.CreateJpeg();

            using (var imageStream = new InMemoryRandomAccessStream())
            {
                //generate stream from MediaCapture
                await captureManager.CapturePhotoToStreamAsync(format, imageStream);

                //create decoder and transform
                BitmapDecoder dec = await BitmapDecoder.CreateAsync(imageStream);

                BitmapTransform transform = new BitmapTransform();

                //roate the image
                transform.Rotation = BitmapRotation.Clockwise90Degrees;
                transform.Bounds   = GetFifteenByNineBounds();

                //get the conversion data that we need to save the cropped and rotated image
                BitmapPixelFormat pixelFormat = dec.BitmapPixelFormat;
                BitmapAlphaMode   alpha       = dec.BitmapAlphaMode;

                //read the PixelData
                PixelDataProvider pixelProvider = await dec.GetPixelDataAsync(
                    pixelFormat,
                    alpha,
                    transform,
                    ExifOrientationMode.RespectExifOrientation,
                    ColorManagementMode.ColorManageToSRgb
                    );

                byte[] pixels = pixelProvider.DetachPixelData();

                //generate the file
                StorageFolder folder      = KnownFolders.SavedPictures;
                StorageFile   capturefile = await folder.CreateFileAsync("photo_" + DateTime.Now.Ticks.ToString() + ".jpg", CreationCollisionOption.ReplaceExisting);

                captureFileName = capturefile.Name;

                //writing directly into the file stream
                using (IRandomAccessStream convertedImageStream = await capturefile.OpenAsync(FileAccessMode.ReadWrite))
                {
                    //write changes to the BitmapEncoder
                    BitmapEncoder enc = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, convertedImageStream);

                    enc.SetPixelData(
                        pixelFormat,
                        alpha,
                        transform.Bounds.Width,
                        transform.Bounds.Height,
                        dec.DpiX,
                        dec.DpiY,
                        pixels
                        );

                    await enc.FlushAsync();
                }
            }
            CleanCapture();

            //load saved image
            LoadCapturedphoto(captureFileName);
        }
Beispiel #22
0
        /// <summary>
        /// Applies the user-provided scale and rotation operation to a new image file picked by the user.
        /// This method writes the edited pixel data to the new file without
        /// any regard to existing metadata or other information in the original file.
        /// </summary>
        private async void SaveAs_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                rootPage.NotifyUser("Saving to a new file...", NotifyType.StatusMessage);

                StorageFile inputFile = await m_futureAccess.GetFileAsync(m_fileToken);

                StorageFile outputFile = await Helpers.GetFileFromSavePickerAsync();

                Guid encoderId;

                switch (outputFile.FileType)
                {
                case ".png":
                    encoderId = BitmapEncoder.PngEncoderId;
                    break;

                case ".bmp":
                    encoderId = BitmapEncoder.BmpEncoderId;
                    break;

                case ".jpg":
                default:
                    encoderId = BitmapEncoder.JpegEncoderId;
                    break;
                }

                using (IRandomAccessStream inputStream = await inputFile.OpenAsync(FileAccessMode.Read),
                       outputStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
                {
                    // BitmapEncoder expects an empty output stream; the user may have selected a
                    // pre-existing file.
                    outputStream.Size = 0;

                    // Get pixel data from the decoder. We apply the user-requested transforms on the
                    // decoded pixels to take advantage of potential optimizations in the decoder.
                    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(inputStream);

                    BitmapTransform transform = new BitmapTransform();

                    // Note that we are requesting the oriented pixel dimensions, and not applying
                    // EXIF orientation in the BitmapTransform. We will request oriented pixel data
                    // later in the BitmapDecoder.GetPixelDataAsync() call.
                    transform.ScaledHeight = (uint)(decoder.OrientedPixelHeight * m_scaleFactor);
                    transform.ScaledWidth  = (uint)(decoder.OrientedPixelWidth * m_scaleFactor);
                    transform.Rotation     = Helpers.ConvertToBitmapRotation(m_userRotation);

                    // The BitmapDecoder indicates what pixel format and alpha mode best match the
                    // natively stored image data. This can provide a performance and/or quality gain.
                    BitmapPixelFormat format = decoder.BitmapPixelFormat;
                    BitmapAlphaMode   alpha  = decoder.BitmapAlphaMode;

                    PixelDataProvider pixelProvider = await decoder.GetPixelDataAsync(
                        format,
                        alpha,
                        transform,
                        ExifOrientationMode.RespectExifOrientation,
                        ColorManagementMode.ColorManageToSRgb
                        );

                    byte[] pixels = pixelProvider.DetachPixelData();

                    // Write the pixel data onto the encoder. Note that we can't simply use the
                    // BitmapTransform.ScaledWidth and ScaledHeight members as the user may have
                    // requested a rotation (which is applied after scaling).
                    BitmapEncoder encoder = await BitmapEncoder.CreateAsync(encoderId, outputStream);

                    encoder.SetPixelData(
                        format,
                        alpha,
                        (uint)((double)m_displayWidthNonScaled * m_scaleFactor),
                        (uint)((double)m_displayHeightNonScaled * m_scaleFactor),
                        decoder.DpiX,
                        decoder.DpiY,
                        pixels
                        );

                    await encoder.FlushAsync();

                    rootPage.NotifyUser("Successfully saved a copy: " + outputFile.Name, NotifyType.StatusMessage);
                }
            }
            catch (Exception err)
            {
                rootPage.NotifyUser("Error: " + err.Message, NotifyType.ErrorMessage);
                ResetPersistedState();
                ResetSessionState();
            }
        }
Beispiel #23
0
        public async Task <StorageFile> SaveToFile(WriteableBitmap image, string file_name, Windows.Storage.CreationCollisionOption collision, BitmapPixelFormat image_format, BitmapAlphaMode alpha_mode)
        {
            var file = await KnownFolders.PicturesLibrary.CreateFileAsync(file_name, collision);

            using (IRandomAccessStream image_stream = await file.OpenAsync(FileAccessMode.ReadWrite))
            {
                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, image_stream);

                Stream pixel_stream = image.PixelBuffer.AsStream();

                byte[] pixel_array = new byte[pixel_stream.Length];

                await pixel_stream.ReadAsync(pixel_array, 0, pixel_array.Length);

                encoder.SetPixelData(image_format, alpha_mode,
                                     (uint)image.PixelWidth,
                                     (uint)image.PixelHeight,
                                     96.0,
                                     96.0,
                                     pixel_array);
                await encoder.FlushAsync();
            }
            return(file);
        }