/// <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)); }
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); }
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(); }
/// <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); }
/// <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(); }
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; } } }
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(); }
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); }
/// <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); } }
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 }
/// <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); }
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; }
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); } }
public static void SetBitmapAlphaMode(DependencyObject obj, BitmapAlphaMode value) { obj.SetValue(BitmapAlphaModeProperty, value); }
/// <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); }
/// <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(); } }
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); }