//public List<ARDocument> academicResult = new List<ARDocument>(); //public string academicErrInfo = ""; //public List<ARDocument> parseResults = null; #if !UNITY_EDITOR /// <summary> /// Do OCR with Azure service /// </summary> /// <param name="imageName">Image path in CameraRoll</param> /// <param name="topLeft"></param> /// <param name="botRight"></param> public async void MakeOCRRequest(string imageName, Vector2 topLeft, Vector2 botRight) { // Check the boundary double widthRatio = botRight.x - topLeft.x; double heightRatio = botRight.y - topLeft.y; ocrStatus = SERVICE_STATUS.PENDING; Debug.Log(string.Format("OCR on file:{0}, start point {1}, size {2}, {3}", imageName, topLeft.ToString(), widthRatio, heightRatio)); HttpClient client = new HttpClient(); // Request headers. client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", azureKey); // Request parameters. string requestParameters = "language=en&detectOrientation=true"; // Assemble the URI for the REST API Call. string uri = azureUri + "ocr?" + requestParameters; HttpResponseMessage response; // Request body. Posts a locally stored JPEG image. byte[] byteData = new byte[1]; byte[] croppedBytes = new byte[1]; /* Crop Function by Diederik Krols. * Refer: https://github.com/XamlBrewer/UWP-ImageCropper-/blob/master/XamlBrewer.Uwp.Controls/Helpers/CropBitmap.cs * */ StorageFolder storageFolder = KnownFolders.CameraRoll; var file = (StorageFile)await storageFolder.TryGetItemAsync(imageName); uint width = 0, height = 0; if (file == null) { string errInfo = "MakeOCRRequest Error: Image File not exist." + imageName; Debug.Log(errInfo); ocrResult = errInfo; ocrStatus = SERVICE_STATUS.ERROR; return; } using (var stream = await file.OpenAsync(FileAccessMode.Read)) { // Create a decoder from the stream. With the decoder, we can get the properties of the image. BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); double originalCroppedWidth = decoder.PixelWidth * widthRatio + 2; double originalCroppedHeight = decoder.PixelHeight * heightRatio + 2; // make sure the image is larger than 50x50 in real pixels. double scale = Math.Max(1.0f, Math.Max(AZURE_API_MIN_SIZE / originalCroppedWidth, AZURE_API_MIN_SIZE / originalCroppedHeight)); uint startPointX = (uint)Math.Floor(decoder.PixelWidth * topLeft.x * scale) - 1; uint startPointY = (uint)Math.Floor(decoder.PixelHeight * topLeft.y * scale) - 1; width = (uint)Math.Floor(originalCroppedWidth * scale); height = (uint)Math.Floor(originalCroppedHeight * scale); // The scaledSize of original image. uint scaledWidth = (uint)Math.Floor(decoder.PixelWidth * scale); uint scaledHeight = (uint)Math.Floor(decoder.PixelHeight * scale); // Refine the start point and the size. if (startPointX + width > scaledWidth) { startPointX = scaledWidth - width; } if (startPointY + height > scaledHeight) { startPointY = scaledHeight - height; } // Get the cropped pixels. BitmapTransform transform = new BitmapTransform(); BitmapBounds bounds = new BitmapBounds(); bounds.X = startPointX; bounds.Y = startPointY; bounds.Height = height; bounds.Width = width; transform.Bounds = bounds; transform.ScaledWidth = scaledWidth; transform.ScaledHeight = scaledHeight; // Get the cropped pixels within the bounds of transform. PixelDataProvider pix = await decoder.GetPixelDataAsync( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.ColorManageToSRgb); croppedBytes = pix.DetachPixelData(); } // Again, I have to save to file stream /* byte[] to image. * https://code.msdn.microsoft.com/windowsapps/How-to-save-WriteableBitmap-bd23d455 * */ var tempFile = await storageFolder.CreateFileAsync("tempOCR.jpg", CreationCollisionOption.GenerateUniqueName); using (var stream = await tempFile.OpenAsync(FileAccessMode.ReadWrite)) { BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream); encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, width, height, 96, 96, croppedBytes); await encoder.FlushAsync(); var reader = new DataReader(stream.GetInputStreamAt(0)); byteData = new byte[stream.Size]; await reader.LoadAsync((uint)stream.Size); reader.ReadBytes(byteData); } await tempFile.DeleteAsync(); using (ByteArrayContent content = new ByteArrayContent(byteData)) { // This example uses content type "application/octet-stream". // The other content types you can use are "application/json" and "multipart/form-data". content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); // Execute the REST API call. response = await client.PostAsync(uri, content); // Get the JSON response. string contentString = await response.Content.ReadAsStringAsync(); // Display the JSON response. Debug.Log("\nResponse:\n"); Debug.Log(JsonPrettyPrint(contentString)); // Parse to output the result. var result = JsonConvert.DeserializeObject <JSONOCR.RootObject>(contentString); var texts = new List <string>(); foreach (var region in result.regions) { foreach (var line in region.lines) { foreach (var word in line.words) { texts.Add(word.text); } } } if (texts.Count > 0) { ocrResult = string.Join(" ", texts); Debug.Log("MakeOCRRequest succeeded:" + ocrResult); ocrStatus = SERVICE_STATUS.DONE; } else { string errInfo = "MakeOCRRequest succeeded but the result is empty."; ocrResult = errInfo; Debug.Log(errInfo); ocrStatus = SERVICE_STATUS.ERROR; } } }
private async void EncodeBtn_Click(object sender, RoutedEventArgs e) { if (m_files.Count == 0) { statusText.Text = "You must select one image at least."; return; } // Create the video file via file picker. FileSavePicker savePicker = new FileSavePicker(); savePicker.SuggestedStartLocation = PickerLocationId.VideosLibrary; savePicker.FileTypeChoices.Add("MP4 File", new List <string>() { ".mp4" }); savePicker.SuggestedFileName = "output"; StorageFile videoFile = await savePicker.PickSaveFileAsync(); if (videoFile != null) { IRandomAccessStream videoStream = await videoFile.OpenAsync(FileAccessMode.ReadWrite); m_picture = new PictureWriter(videoStream, m_videoWidth, m_videoHeight); // Add frames to the video. ProcessVideoRing.IsActive = true; statusText.Text = "Encoding..."; foreach (StorageFile file in m_files) { Windows.Storage.FileProperties.ImageProperties properties = await file.Properties.GetImagePropertiesAsync(); float scaleOfWidth = (float)m_videoWidth / properties.Width; float scaleOfHeight = (float)m_videoHeight / properties.Height; float scale = scaleOfHeight > scaleOfWidth ? scaleOfWidth : scaleOfHeight; uint width = (uint)(properties.Width * scale); uint height = (uint)(properties.Height * scale); using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read)) { for (int i = 0; i < 10; ++i) { BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); PixelDataProvider dataProvider = await decoder.GetPixelDataAsync( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, new BitmapTransform { ScaledWidth = width, ScaledHeight = height }, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb); m_picture.AddFrame(dataProvider.DetachPixelData(), (int)width, (int)height); } } } m_picture.Finalize(); m_picture = null; statusText.Text = "The image files are encoded successfully. You can review the video."; ProcessVideoRing.IsActive = false; videoStream.Dispose(); videoStream = null; videoStream = await videoFile.OpenAsync(FileAccessMode.Read); VideoElement.SetSource(videoStream, videoFile.ContentType); } }
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(); } }
private async Task <byte[]> GetImageAsByteAsync(Guid format, int quality, int desiredWidth, int desiredHeight) { if (Control == null || Control.Source == null) { return(null); } var bitmap = Control.Source as WriteableBitmap; if (bitmap == null) { return(null); } byte[] pixels = null; uint pixelsWidth = (uint)bitmap.PixelWidth; uint pixelsHeight = (uint)bitmap.PixelHeight; if (desiredWidth != 0 || desiredHeight != 0) { double widthRatio = (double)desiredWidth / (double)bitmap.PixelWidth; double heightRatio = (double)desiredHeight / (double)bitmap.PixelHeight; double scaleRatio = Math.Min(widthRatio, heightRatio); if (desiredWidth == 0) { scaleRatio = heightRatio; } if (desiredHeight == 0) { scaleRatio = widthRatio; } uint aspectWidth = (uint)((double)bitmap.PixelWidth * scaleRatio); uint aspectHeight = (uint)((double)bitmap.PixelHeight * scaleRatio); using (var tempStream = new InMemoryRandomAccessStream()) { byte[] tempPixels = await GetBytesFromBitmapAsync(bitmap); var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, tempStream); encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, pixelsWidth, pixelsHeight, 96, 96, tempPixels); await encoder.FlushAsync(); tempStream.Seek(0); BitmapDecoder decoder = await BitmapDecoder.CreateAsync(tempStream); BitmapTransform transform = new BitmapTransform() { ScaledWidth = aspectWidth, ScaledHeight = aspectHeight, InterpolationMode = BitmapInterpolationMode.Linear }; PixelDataProvider pixelData = await decoder.GetPixelDataAsync( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage); pixels = pixelData.DetachPixelData(); pixelsWidth = aspectWidth; pixelsHeight = aspectHeight; } } else { pixels = await GetBytesFromBitmapAsync(bitmap); } using (var stream = new InMemoryRandomAccessStream()) { var encoder = await BitmapEncoder.CreateAsync(format, stream); encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, pixelsWidth, pixelsHeight, 96, 96, pixels); await encoder.FlushAsync(); stream.Seek(0); var bytes = new byte[stream.Size]; await stream.ReadAsync(bytes.AsBuffer(), (uint)stream.Size, InputStreamOptions.None); return(bytes); } }
public async void get_blurriness() { byte[] picdata; using (var fp = await path.OpenAsync(FileAccessMode.Read)) { BitmapDecoder bd = await BitmapDecoder.CreateAsync(fp); BitmapPixelFormat fmt = bd.BitmapPixelFormat; uint width = bd.PixelWidth; uint height = bd.PixelHeight; PixelDataProvider pd = await bd.GetPixelDataAsync(); picdata = pd.DetachPixelData(); exposure = 0; float mean = 0, M2 = 0; int n = 0; switch (fmt) { case BitmapPixelFormat.Bgra8: case BitmapPixelFormat.Rgba8: for (uint x = 1; x < width - 1; x++) { for (uint y = 1; y < height - 1; y++) { n++; byte c1 = picdata[(x + width * y) * 4]; byte c2 = picdata[(x + width * y) * 4 + 1]; byte c3 = picdata[(x + width * y) * 4 + 2]; int brightness = c1 + c2 + c3; exposure += 255 - brightness / 3; byte ct1 = picdata[(x + width * (y - 1)) * 4]; byte ct2 = picdata[(x + width * (y - 1)) * 4 + 1]; byte ct3 = picdata[(x + width * (y - 1)) * 4 + 2]; int top = ct1 + ct2 + ct3; byte cb1 = picdata[(x + width * (y + 1)) * 4]; byte cb2 = picdata[(x + width * (y + 1)) * 4 + 1]; byte cb3 = picdata[(x + width * (y + 1)) * 4 + 2]; int bottom = cb1 + cb2 + cb3; byte cl1 = picdata[(x + width * y - 1) * 4]; byte cl2 = picdata[(x + width * y - 1) * 4 + 1]; byte cl3 = picdata[(x + width * y - 1) * 4 + 2]; int left = cl1 + cl2 + cl3; byte cr1 = picdata[(x + width * y - 1) * 4]; byte cr2 = picdata[(x + width * y - 1) * 4 + 1]; byte cr3 = picdata[(x + width * y - 1) * 4 + 2]; int right = cr1 + cr2 + cr3; int laplacian = left + top + right + bottom - brightness * 4; float delta = laplacian - mean; mean += delta / n; float delta2 = laplacian - mean; M2 += delta2 * delta; } } blur = M2 / (n - 1); exposure /= n; break; case BitmapPixelFormat.Rgba16: break; default: break; } } }
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); } }
/// <summary> /// 改变图片大小 /// </summary> /// <param name="sourceStream">包含图片数据的数据流</param> /// <param name="scaleLong">如果图片长大于宽,那么此为改编后的长度,反之是改变后的高度</param> /// <returns></returns> public static async Task <IRandomAccessStream> ResizeImage(IRandomAccessStream sourceStream, uint scaleLong) { try { BitmapDecoder decoder = await BitmapDecoder.CreateAsync(sourceStream); uint height = decoder.PixelHeight; uint weight = decoder.PixelWidth; double rate; uint destHeight = height; uint destWeight = weight; if (weight > height) { rate = scaleLong / (double)weight; destHeight = weight > scaleLong ? (uint)(rate * height) : height; destWeight = scaleLong; } else { rate = scaleLong / (double)height; destWeight = height > scaleLong ? (uint)(rate * weight) : weight; destHeight = scaleLong; } BitmapTransform transform = new BitmapTransform() { ScaledWidth = destWeight, ScaledHeight = destHeight }; PixelDataProvider pixelData = await decoder.GetPixelDataAsync( BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.DoNotColorManage); var folder = ApplicationData.Current.TemporaryFolder; var tempfile = await folder.CreateFileAsync("temp.jpg", CreationCollisionOption.GenerateUniqueName); IRandomAccessStream destStream = await tempfile.OpenAsync(FileAccessMode.ReadWrite); BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, destStream); encoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, transform.ScaledWidth, transform.ScaledHeight, 100, 100, pixelData.DetachPixelData()); await encoder.FlushAsync(); //REMEMBER destStream.Seek(0); await tempfile.DeleteAsync(StorageDeleteOption.PermanentDelete); return(destStream); } catch (Exception e) { var task = ExceptionHelper.WriteRecordAsync(e, nameof(BitmapHandleHelper), nameof(ResizeImage)); return(null); } }
private async Task <byte[]> GetIntFromPixel(BitmapDecoder decoder) { var pixels = await decoder.GetPixelDataAsync(); return(pixels.DetachPixelData()); }
public static async Task <bool> CreateSnapshot(string key, Func <IRandomAccessStream, Task> create) { try { InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream(); await create(ms); BitmapDecoder decoder = await BitmapDecoder.CreateAsync(ms); PixelDataProvider pixelData = await decoder.GetPixelDataAsync( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, new BitmapTransform(), ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage); byte[] oldPixelData = pixelData.DetachPixelData(); ImageCropper cropper = new ImageCropper(oldPixelData, decoder.PixelWidth, decoder.PixelHeight, BitmapPixelFormat.Bgra8); uint newWidth, newHeight; byte[] newPixelData = cropper.Crop(out newWidth, out newHeight); //InMemoryRandomAccessStream newMemroyBitmap = new InMemoryRandomAccessStream(); //var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, newMemroyBitmap); //encoder.SetPixelData( // BitmapPixelFormat.Bgra8, // BitmapAlphaMode.Straight, // (uint)newWidth, // (uint)newHeight, // decoder.DpiX, // decoder.DpiY, // newPixelData); //await encoder.FlushAsync(); //newMemroyBitmap.Seek(0); //decoder = await BitmapDecoder.CreateAsync(newMemroyBitmap); //// Create a small thumbnail. //int longlength = 96, width = 0, height = 0; //double srcwidth = decoder.PixelWidth, srcheight = decoder.PixelHeight; //double factor = srcwidth / srcheight; //if (factor < 1) //{ // height = longlength; // width = (int)(longlength * factor); //} //else //{ // width = longlength; // height = (int)(longlength / factor); //} //BitmapTransform transform = new BitmapTransform(); //transform.ScaledHeight = (uint)height; //transform.ScaledWidth = (uint)width; //pixelData = await decoder.GetPixelDataAsync( // BitmapPixelFormat.Bgra8, // BitmapAlphaMode.Straight, // transform, // ExifOrientationMode.RespectExifOrientation, // ColorManagementMode.DoNotColorManage); Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; var file = await localFolder.CreateFileAsync(key + ChmSnapshotEntension, CreationCollisionOption.ReplaceExisting); using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite)) { var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, fileStream); encoder.SetPixelData( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, newWidth, newHeight, decoder.DpiX, decoder.DpiY, newPixelData); await encoder.FlushAsync(); } return(true); } catch { return(false); } }
/// <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); }
private async Task GetCroppedBitmap(StorageFile originalImgFile, Point startPoint, Size cropSize, double scale, int whichTile) { btnRandomizeButtom.IsEnabled = true; checkForWin = false; textBlockWin.Text = ""; GameGrid.Opacity = 100; if (double.IsNaN(scale) || double.IsInfinity(scale)) { scale = 1; } uint startPointX = (uint)Math.Floor(startPoint.X * scale); uint startPointY = (uint)Math.Floor(startPoint.Y * scale); uint height = (uint)Math.Floor(cropSize.Height * scale); uint width = (uint)Math.Floor(cropSize.Width * scale); using (IRandomAccessStream stream = await originalImgFile.OpenReadAsync()) { BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); uint scaledWidth = (uint)Math.Floor(decoder.PixelWidth * scale); uint scaledHeight = (uint)Math.Floor(decoder.PixelHeight * scale); if (startPointX + width > scaledWidth) { startPointX = scaledWidth - width; } if (startPointY + height > scaledHeight) { startPointY = scaledHeight - height; } // Create cropping BitmapTransform and define the bounds... BitmapTransform transform = new BitmapTransform(); BitmapBounds bounds = new BitmapBounds(); bounds.X = startPointX; bounds.Y = startPointY; bounds.Height = height; bounds.Width = width; transform.Bounds = bounds; transform.ScaledWidth = scaledWidth; transform.ScaledHeight = scaledHeight; // Get the cropped pixels within the bounds of transform... PixelDataProvider pix = await decoder.GetPixelDataAsync( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.ColorManageToSRgb); byte[] pixels = pix.DetachPixelData(); // Stream the bytes into a WriteableBitmap... tiles[whichTile].tileImage = new WriteableBitmap((int)width, (int)height); Stream pixStream = tiles[whichTile].tileImage.PixelBuffer.AsStream(); pixStream.Write(pixels, 0, (int)(width * height * gridWidth)); return; } }
private async Task <ImageBrush> GetImageBrush(uint x, uint y, uint width, uint heigth) { ImageBrush imageBrush = new ImageBrush(); BitmapImage image = this.ImageSource as BitmapImage; Uri uri; if (image != null) { if (image.UriSource != null) { var reg = @"http(s)?://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?"; Uri baseUri = new Uri("ms-appx:///"); Regex regex = new Regex(reg, RegexOptions.IgnoreCase); if (regex.IsMatch(image.UriSource.ToString())) { uri = image.UriSource; } else { uri = new Uri(baseUri, image.UriSource.AbsolutePath); } RandomAccessStreamReference fileStream = RandomAccessStreamReference.CreateFromUri(uri); IRandomAccessStream randomAccessStream = await fileStream.OpenReadAsync(); BitmapDecoder bitmapDecoder = await BitmapDecoder.CreateAsync(randomAccessStream); if (x + width > this.W) { width = (uint)(this.W + 0.5) - x; } if (y + heigth > this.H) { heigth = (uint)(this.H + 0.5) - y; } BitmapTransform bitmapTransform = new BitmapTransform() { ScaledHeight = (uint)this.H, ScaledWidth = (uint)this.W, Rotation = BitmapRotation.None, Flip = BitmapFlip.None, InterpolationMode = BitmapInterpolationMode.NearestNeighbor, Bounds = new BitmapBounds { Width = width, Height = heigth, X = x, Y = y } }; PixelDataProvider pixelDataProvider = await bitmapDecoder.GetPixelDataAsync( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, bitmapTransform, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.DoNotColorManage); byte[] pixelData = pixelDataProvider.DetachPixelData(); BitmapImage bb = new BitmapImage(); WriteableBitmap bitmap = new WriteableBitmap((int)width, (int)heigth); using (Stream data = bitmap.PixelBuffer.AsStream()) { await data.WriteAsync(pixelData, 0, pixelData.Length); } imageBrush.ImageSource = bitmap; } } return(imageBrush); }
internal static async Task LoadTileImageInternalAsync(string imagePath) { string tileName = "dreaming"; uint MaxImageWidth = 360; uint MaxImageHeight = 600; StorageFile origFile = await ApplicationData.Current.LocalFolder.GetFileAsync(imagePath); // open file for the new tile image file StorageFile tileFile = await Windows.Storage.KnownFolders.PicturesLibrary.CreateFileAsync(tileName, CreationCollisionOption.GenerateUniqueName); using (IRandomAccessStream tileStream = await tileFile.OpenAsync(FileAccessMode.ReadWrite)) { // get width and height from the original image IRandomAccessStreamWithContentType stream = await origFile.OpenReadAsync(); ImageProperties properties = await origFile.Properties.GetImagePropertiesAsync(); uint width = properties.Width; uint height = properties.Height; // get proper decoder for the input file - jpg/png/gif BitmapDecoder decoder = await GetProperDecoder(stream, origFile); if (decoder == null) { return; // should not happen } // get byte array of actual decoded image PixelDataProvider data = await decoder.GetPixelDataAsync(); byte[] bytes = data.DetachPixelData(); // create encoder for saving the tile image BitmapPropertySet propertySet = new BitmapPropertySet(); // create class representing target jpeg quality - a bit obscure, but it works BitmapTypedValue qualityValue = new BitmapTypedValue(0.5, PropertyType.Single); propertySet.Add("ImageQuality", qualityValue); // create the target jpeg decoder BitmapEncoder be = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, tileStream, propertySet); be.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, width, height, 96.0, 96.0, bytes); // crop the image, if it's too big if (width > MaxImageWidth || height > MaxImageHeight) { BitmapBounds bounds = new BitmapBounds(); if (width > MaxImageWidth) { bounds.Width = MaxImageWidth; bounds.X = (width - MaxImageWidth) / 2; } else { bounds.Width = width; } if (height > MaxImageHeight) { bounds.Height = MaxImageHeight; bounds.Y = (height - MaxImageHeight) / 2; } else { bounds.Height = height; } be.BitmapTransform.Bounds = bounds; } // save the target jpg to the file await be.FlushAsync(); } }
public async Task <byte[]> EncodeBinary(BitmapDecoder imageDecoder, AnymapProperties properties) { var pixelDataProvider = await imageDecoder.GetPixelDataAsync(); var image = pixelDataProvider.DetachPixelData(); properties.SourcePixelFormat = imageDecoder.BitmapPixelFormat; UInt32 totalPixels = imageDecoder.OrientedPixelWidth * imageDecoder.OrientedPixelHeight; UInt32 bytesNumForPixels = 0; Byte type = 0; WriteBinaryDelegate write = null; bool isContainMaxValue = true; switch (properties.AnymapType) { case AnymapType.Bitmap: bytesNumForPixels = (properties.Width / 8 + (properties.Width % 8 == 0 ? (UInt32)0 : (UInt32)1)) * properties.Height; type = (Byte)'4'; write = WriteP4; isContainMaxValue = false; break; case AnymapType.Graymap: bytesNumForPixels = totalPixels * properties.BytesPerColor; type = (Byte)'5'; write = WriteP5; break; case AnymapType.Pixmap: bytesNumForPixels = totalPixels * 3 * properties.BytesPerColor; type = (Byte)'6'; write = WriteP6; break; } UInt32 bytesForType = 3; UInt32 bytesForSize = (UInt32)properties.Width.ToString().Length + 1 + (UInt32)properties.Height.ToString().Length + 1; UInt32 bytesForMaxV = (UInt32)properties.MaxValue.ToString().Length + 1; UInt32 bytesNum = bytesForType + bytesForSize + (isContainMaxValue ? bytesForMaxV : 0) + bytesNumForPixels; byte[] anymap = new byte[bytesNum]; MemoryStream stream = new MemoryStream(anymap); // Format stream.WriteByte((Byte)'P'); stream.WriteByte(type); stream.WriteByte(0x0a); // Size byte[] widthArr = Encoding.ASCII.GetBytes(properties.Width.ToString()); stream.Write(widthArr, 0, widthArr.Length); stream.WriteByte((Byte)' '); byte[] heightArr = Encoding.ASCII.GetBytes(properties.Height.ToString()); stream.Write(heightArr, 0, heightArr.Length); stream.WriteByte(0x0a); // Maximum pixel value if (isContainMaxValue) { byte[] maxPixelValueArr = Encoding.ASCII.GetBytes(properties.MaxValue.ToString()); stream.Write(maxPixelValueArr, 0, maxPixelValueArr.Length); stream.WriteByte(0x0a); } // Pixels write(image, stream, totalPixels, properties); return(anymap); }
/// <summary> /// Generates a darker bottom on an image /// </summary> /// <param name="filename">filename in LocalFolder</param> /// <param name="outfilename">filename in LocalFolder</param> /// <returns>Awaitable Task</returns> private async static Task DarkenImageBottom(string filename, string outfilename) { var file = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync(filename); BitmapDecoder decoder = null; byte[] sourcePixels = null; using (IRandomAccessStream fileStream = await file.OpenReadAsync()) { decoder = await BitmapDecoder.CreateAsync(fileStream); // Scale image to appropriate size BitmapTransform transform = new BitmapTransform(); PixelDataProvider pixelData = await decoder.GetPixelDataAsync( BitmapPixelFormat.Bgra8, // WriteableBitmap uses BGRA format BitmapAlphaMode.Straight, transform, ExifOrientationMode.IgnoreExifOrientation, // This sample ignores Exif orientation ColorManagementMode.DoNotColorManage ); // An array containing the decoded image data, which could be modified before being displayed sourcePixels = pixelData.DetachPixelData(); fileStream.Dispose(); } for (uint col = 0; col < decoder.PixelWidth; col++) { for (uint row = 0; row < decoder.PixelHeight; row++) { if (row < decoder.PixelHeight * .6) { continue; } uint idx = (row * decoder.PixelWidth + col) * 4; if (decoder.BitmapPixelFormat == BitmapPixelFormat.Bgra8 || decoder.BitmapPixelFormat == BitmapPixelFormat.Rgba8) { var frac = 1 - Math.Sin(((row / (double)decoder.PixelHeight) - .6) * (1 / .4)); byte b = sourcePixels[idx]; byte g = sourcePixels[idx + 1]; byte r = sourcePixels[idx + 2]; sourcePixels[idx] = (byte)(b * frac); sourcePixels[idx + 1] = (byte)(g * frac); sourcePixels[idx + 2] = (byte)(r * frac); } } } var file2 = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(outfilename, CreationCollisionOption.ReplaceExisting); var str = await file2.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite); BitmapEncoder enc = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, str); enc.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, decoder.PixelWidth, decoder.PixelHeight, decoder.DpiX, decoder.DpiY, sourcePixels); await enc.FlushAsync(); str.Dispose(); }
/// <summary> /// Handle the returned file from file picker /// This method is triggered by ContinuationManager based on ActivationKind /// </summary> /// <param name="args">File save picker continuation activation argment. It cantains the file user selected with file save picker </param> public async void ContinueFileSavePicker(FileSavePickerContinuationEventArgs args) { StorageFile videoFile = args.File; if (videoFile != null) { IRandomAccessStream videoStream = await videoFile.OpenAsync(FileAccessMode.ReadWrite); m_picture = new PictureWriter(videoStream, m_videoWidth, m_videoHeight); // Add frames to the video. ProcessVideoRing.IsActive = true; VideoElement.AreTransportControlsEnabled = false; ImageBtn.IsEnabled = false; EncodeBtn.IsEnabled = false; statusText.Text = "Encoding..."; foreach (StorageFile file in m_files) { Windows.Storage.FileProperties.ImageProperties properties = await file.Properties.GetImagePropertiesAsync(); float scaleOfWidth = (float)m_videoWidth / properties.Width; float scaleOfHeight = (float)m_videoHeight / properties.Height; float scale = scaleOfHeight > scaleOfWidth ? scaleOfWidth : scaleOfHeight; uint width = (uint)(properties.Width * scale); uint height = (uint)(properties.Height * scale); using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read)) { for (int i = 0; i < 10; ++i) { BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); PixelDataProvider dataProvider = await decoder.GetPixelDataAsync( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, new BitmapTransform { ScaledWidth = width, ScaledHeight = height }, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb); m_picture.AddFrame(dataProvider.DetachPixelData(), (int)width, (int)height); } } } m_picture.Finalize(); m_picture = null; VideoElement.AreTransportControlsEnabled = true; ImageBtn.IsEnabled = true; EncodeBtn.IsEnabled = true; statusText.Text = "The image files are encoded successfully. You can review the video."; ProcessVideoRing.IsActive = false; videoStream.Dispose(); videoStream = null; videoStream = await videoFile.OpenAsync(FileAccessMode.Read); VideoElement.SetSource(videoStream, videoFile.ContentType); } }
public static async Task <string> HttpPost(StorageFile inFile) { HttpClient httpClient = new HttpClient(); uint MaxImageWidth = 480; uint MaxImageHeight = 800; uint width; uint height; string posturi = Config.apiChatImage; HttpMultipartFormDataContent fileContent = new HttpMultipartFormDataContent(); var inStream = await inFile.OpenReadAsync(); InMemoryRandomAccessStream outStream = new InMemoryRandomAccessStream(); BitmapDecoder decoder = await ImageHelp.GetProperDecoder(inStream, inFile); if (decoder.OrientedPixelWidth > MaxImageWidth && decoder.OrientedPixelHeight > MaxImageHeight) { width = MaxImageWidth; height = MaxImageHeight; } else { width = decoder.OrientedPixelWidth; height = decoder.OrientedPixelHeight; } PixelDataProvider provider = await decoder.GetPixelDataAsync(); byte[] data = provider.DetachPixelData(); //获取像素数据的字节数组 BitmapPropertySet propertySet = new BitmapPropertySet(); BitmapTypedValue qualityValue = new BitmapTypedValue(0.5, PropertyType.Single); propertySet.Add("ImageQuality", qualityValue); var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, outStream, propertySet); //建立编码器 encoder.SetPixelData(decoder.BitmapPixelFormat, decoder.BitmapAlphaMode, decoder.OrientedPixelWidth, decoder.OrientedPixelHeight, decoder.DpiX, decoder.DpiY, data ); encoder.BitmapTransform.ScaledWidth = width; encoder.BitmapTransform.ScaledHeight = height; await encoder.FlushAsync(); HttpStreamContent streamContent1 = new HttpStreamContent(outStream); fileContent.Add(streamContent1, "pic", inFile.Name); HttpResponseMessage response = await httpClient.PostAsync(new Uri(posturi), fileContent); return(await response.Content.ReadAsStringAsync()); }
/// <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); }
private async void CUButton_Click(object sender, RoutedEventArgs e) { if (title.Text == "") { var i = new MessageDialog("Title Empty!").ShowAsync(); return; } if (detail.Text == "") { var i = new MessageDialog("Detail Empty!").ShowAsync(); return; } if (date.Date.Date < DateTime.Today.Date) { var i = new MessageDialog("Invalid Date!").ShowAsync(); return; } WriteableBitmap defaultimage = null; StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/background.jpg")); if (file != null) { using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read)) { BitmapDecoder bitmapDecoder = await BitmapDecoder.CreateAsync(fileStream); BitmapTransform dummyTransform = new BitmapTransform(); PixelDataProvider pixelDataProvider = await bitmapDecoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, dummyTransform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb); byte[] pixelData = pixelDataProvider.DetachPixelData(); defaultimage = new WriteableBitmap( (int)bitmapDecoder.OrientedPixelWidth, (int)bitmapDecoder.OrientedPixelHeight); using (Stream pixelStream = defaultimage.PixelBuffer.AsStream()) { await pixelStream.WriteAsync(pixelData, 0, pixelData.Length); } } } if (CUButton.Content.ToString() == "Create") { if (writeableBitmap == null) { ViewModel.AddTodoItem(title.Text, detail.Text, defaultimage, date.Date.DateTime); ViewModel.AllItems.Last().imageFile = file; } else { ViewModel.AddTodoItem(title.Text, detail.Text, writeableBitmap, date.Date.DateTime); ViewModel.AllItems.Last().imageFile = imageFile; } } else { if (writeableBitmap == null) { ViewModel.SelectedItem.imageFile = file; ViewModel.UpdateTodoItem(ViewModel.SelectedItem.id, title.Text, detail.Text, defaultimage, date.Date.DateTime); } else { ViewModel.SelectedItem.imageFile = imageFile; ViewModel.UpdateTodoItem(ViewModel.SelectedItem.id, title.Text, detail.Text, writeableBitmap, date.Date.DateTime); } } Frame.Navigate(typeof(MainPage), ViewModel); }
private async Task LoadSaveFileAsync(StorageFile outputFile) { try { StorageFile inputFile = await m_futureAccess.GetFileAsync(m_fileToken); 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(); // 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 = Helpers.ConvertToBitmapRotation(m_userRotation); // Fant is a relatively high quality interpolation mode. transform.InterpolationMode = BitmapInterpolationMode.Fant; // 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(); } }
#pragma warning disable CA1416 // Validate platform compatibility private void ApplyEffects(bool recreateSession = true) { if (!initialized_ || decoder_ == null) { return; } PerformanceMetricsMonitor.ClearLog(); if (recreateSession) { RecreateSessions(); } // TensorizeWithVideoFrame(); long start, stop; // Tensorize start = HighResolutionClock.UtcNow(); var pixelDataProvider = decoder_.GetPixelDataAsync().GetAwaiter().GetResult(); var bytes = pixelDataProvider.DetachPixelData(); var buffer = bytes.AsBuffer(); // Does this do a copy?? var inputRawTensor = TensorUInt8Bit.CreateFromBuffer(new long[] { 1, buffer.Length }, buffer); // 3 channel NCHW var nextOutputShape = new long[] { 1, 3, currentImageHeight_, currentImageWidth_ }; var intermediateTensor = TensorFloat.Create(nextOutputShape); var tensorizationBinding = Evaluate(tensorizationSession_, inputRawTensor, intermediateTensor); stop = HighResolutionClock.UtcNow(); var tensorizationDuration = HighResolutionClock.DurationInMs(start, stop); // Resize start = HighResolutionClock.UtcNow(); TensorFloat resizeOutput = null; LearningModelBinding resizeBinding = null; if (resizeEffectSession_ != null) { nextOutputShape = new long[] { 1, 3, 224, 224 }; resizeOutput = TensorFloat.Create(nextOutputShape); resizeBinding = Evaluate(resizeEffectSession_, intermediateTensor, resizeOutput); intermediateTensor = resizeOutput; } stop = HighResolutionClock.UtcNow(); var resizeDuration = HighResolutionClock.DurationInMs(start, stop); // Pixel Swizzle start = HighResolutionClock.UtcNow(); TensorFloat swizzleOutput = null; LearningModelBinding swizzleBinding = null; if (pixelSwizzleEffectSession_ != null) { swizzleOutput = TensorFloat.Create(nextOutputShape); swizzleBinding = Evaluate(pixelSwizzleEffectSession_, intermediateTensor, swizzleOutput); intermediateTensor = swizzleOutput; } stop = HighResolutionClock.UtcNow(); var swizzleDuration = HighResolutionClock.DurationInMs(start, stop); // Blur start = HighResolutionClock.UtcNow(); TensorFloat blurOutput = null; LearningModelBinding blurBinding = null; if (blurSharpenEffectSession_ != null) { blurOutput = TensorFloat.Create(nextOutputShape); blurBinding = Evaluate(blurSharpenEffectSession_, intermediateTensor, blurOutput); intermediateTensor = blurOutput; } stop = HighResolutionClock.UtcNow(); var blurDuration = HighResolutionClock.DurationInMs(start, stop); // Contrast start = HighResolutionClock.UtcNow(); TensorFloat contrastOutput = null; LearningModelBinding contrastBinding = null; if (contrastEffectSession_ != null) { contrastOutput = TensorFloat.Create(nextOutputShape); contrastBinding = EvaluateContrastAndBrightnessSession(intermediateTensor, contrastOutput); intermediateTensor = contrastOutput; } stop = HighResolutionClock.UtcNow(); var contrastDuration = HighResolutionClock.DurationInMs(start, stop); // Artistic Effects start = HighResolutionClock.UtcNow(); LearningModelBinding artistiicEffectsBinding = null; if (artisticEffectsEffectSession_ != null) { var output = TensorFloat.Create(nextOutputShape); artistiicEffectsBinding = Evaluate(artisticEffectsEffectSession_, intermediateTensor, output); intermediateTensor = output; } stop = HighResolutionClock.UtcNow(); var artisticEffectsDuration = HighResolutionClock.DurationInMs(start, stop); // Orientation start = HighResolutionClock.UtcNow(); TensorFloat orientationOutput = null; LearningModelBinding orientationBinding = null; if (orientationEffectSession_ != null) { var orientationEffect = (OrientationPicker.SelectedItem as OrientationViewModel).Tag; if (orientationEffect == Effect.RotateLeft90 || orientationEffect == Effect.RotateRight90) { nextOutputShape = new long[] { 1, 3, nextOutputShape[3], nextOutputShape[2] }; orientationOutput = TensorFloat.Create(nextOutputShape); } else { orientationOutput = TensorFloat.Create(nextOutputShape); } orientationBinding = Evaluate(orientationEffectSession_, intermediateTensor, orientationOutput); intermediateTensor = orientationOutput; } stop = HighResolutionClock.UtcNow(); var orientationDuration = HighResolutionClock.DurationInMs(start, stop); // Detensorize start = HighResolutionClock.UtcNow(); var shape = intermediateTensor.Shape; var n = (int)shape[0]; var c = (int)shape[1]; var h = (int)shape[2]; var w = (int)shape[3]; // Rather than writing the data into the software bitmap ourselves from a Tensor (which may be on the gpu) // we call an indentity model to move the gpu memory back to the cpu via WinML de-tensorization. var outputImage = new SoftwareBitmap(BitmapPixelFormat.Bgra8, w, h, BitmapAlphaMode.Premultiplied); var outputFrame = VideoFrame.CreateWithSoftwareBitmap(outputImage); var descriptor = detensorizationSession_.Model.InputFeatures[0] as TensorFeatureDescriptor; var detensorizerShape = descriptor.Shape; if (c != detensorizerShape[1] || h != detensorizerShape[2] || w != detensorizerShape[3]) { detensorizationSession_ = CreateLearningModelSession(TensorizationModels.IdentityNCHW(n, c, h, w)); } var detensorizationBinding = Evaluate(detensorizationSession_, intermediateTensor, outputFrame, true); stop = HighResolutionClock.UtcNow(); var detensorizationDuration = HighResolutionClock.DurationInMs(start, stop); // Render var softwareBitmap = outputFrame.SoftwareBitmap; RenderingHelpers.BindSoftwareBitmapToImageControl(InputImage, softwareBitmap); PerformanceMetricsMonitor.Log("Tensorize", tensorizationDuration); PerformanceMetricsMonitor.Log("Resize Effect", resizeDuration); PerformanceMetricsMonitor.Log("Swizzle Effect", swizzleDuration); PerformanceMetricsMonitor.Log("Blur Effect", blurDuration); PerformanceMetricsMonitor.Log("Contrast Effect", contrastDuration); PerformanceMetricsMonitor.Log("Artistic Effect", artisticEffectsDuration); PerformanceMetricsMonitor.Log("Orientation Effect", orientationDuration); PerformanceMetricsMonitor.Log("Detensorize", detensorizationDuration); }
public static async Task <IMatrixProject> LoadFromImageAsync(this StorageFile file, uint maximumHeight, uint maximumWidth) { IMatrixProject returnValue = new MatrixProject() { ColorMatrix = new ColorMatrix(maximumWidth, maximumHeight) }; using (Stream imageStream = await file.OpenStreamForReadAsync()) { BitmapDecoder decoder = await BitmapDecoder.CreateAsync(imageStream.AsRandomAccessStream()); // *** // *** Get the pixel mapper. // *** IPixelMapperFactory factory = new PixelMapperFactory(); IPixelMapper mapper = await factory.GetMapper(decoder.BitmapPixelFormat); PixelDataProvider data = await decoder.GetPixelDataAsync(); byte[] bytes = data.DetachPixelData(); uint width = decoder.OrientedPixelWidth; uint height = decoder.OrientedPixelHeight; if (width > maximumWidth || height > maximumHeight) { (bytes, width, height) = await decoder.ResizeImageAsync(maximumHeight, maximumWidth); } if (width <= maximumWidth && height <= maximumHeight) { uint startColumn = (uint)((maximumWidth - width) / 2.0); uint startRow = (uint)((maximumHeight - height) / 2.0); for (uint row = 0; row < height; row++) { for (uint column = 0; column < width; column++) { // *** // *** Get the color from the image data. // *** Color color = await mapper.GetPixelAsync(bytes, row, column, width, height); // *** // *** The default color item type is pixel. // *** ColorItem.ColorItemType itemType = ColorItem.ColorItemType.Pixel; if (color.A == 0 && (color.R != 0 || color.G != 0 || color.B != 0)) { // *** // *** An item with color and an alpha of 0 is a // *** sand pixel. // *** itemType = ColorItem.ColorItemType.Sand; color.A = 255; } else if (color.A == 0) { // *** // *** An item without color (black) and an alpha // *** of 0 is a sand pixel. // *** itemType = ColorItem.ColorItemType.Background; } await returnValue.ColorMatrix.SetItem(row + startRow, column + startColumn, color, itemType); } } // *** // *** Read the meta data. // *** await returnValue.RestoreImageMetaData(file); } else { throw new BadImageFormatException(); } } return(returnValue); }
public async Task <StorageFile> GetCroppedBitmapAsync(StorageFile savedStorageFile, uint startPointX, uint startPointY, uint width, uint height, double scale) { if (double.IsNaN(scale) || double.IsInfinity(scale)) { scale = 1; } using (IRandomAccessStream stream = await savedStorageFile.OpenReadAsync()) { // Create a decoder from the stream. With the decoder, we can get // the properties of the image. BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); // The scaledSize of original image. uint scaledWidth = (uint)Math.Floor(decoder.PixelWidth * scale); uint scaledHeight = (uint)Math.Floor(decoder.PixelHeight * scale); // Refine the start point and the size. /* if (startPointX + width > scaledWidth) * { * startPointX = scaledWidth - width; * } * * if (startPointY + height > scaledHeight) * { * startPointY = scaledHeight - height; * } */ // Create cropping BitmapTransform and define the bounds. BitmapTransform transform = new BitmapTransform(); BitmapBounds bounds = new BitmapBounds(); bounds.X = startPointX; bounds.Y = startPointY; bounds.Height = height; bounds.Width = width; transform.Bounds = bounds; // transform.ScaledWidth = 100; // transform.ScaledHeight = 100; // Get the cropped pixels within the bounds of transform. PixelDataProvider pix = await decoder.GetPixelDataAsync( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.ColorManageToSRgb); //new var originalPixelWidth = decoder.PixelWidth; var originalPixelHeight = decoder.PixelHeight; // byte[] pixels = pix.DetachPixelData(); // Stream the bytes into a WriteableBitmap WriteableBitmap cropBmp = new WriteableBitmap((int)width, (int)height); Stream pixStream = cropBmp.PixelBuffer.AsStream(); pixStream.Write(pixels, 0, (int)(width * height * 4)); var fileName = Guid.NewGuid() + "Bps1.jpeg"; Guid bitMapEncoderGuid = BitmapEncoder.JpegEncoderId; var file = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName); using (var irStream = await file.OpenAsync(FileAccessMode.ReadWrite)) { // var bmenc = await BitmapEncoder.CreateAsync(bitMapEncoderGuid, irStream); var bmenc = await BitmapEncoder.CreateForTranscodingAsync(irStream, decoder); Stream sstrm = cropBmp.PixelBuffer.AsStream(); byte[] pxls = new byte[sstrm.Length]; await sstrm.ReadAsync(pxls, 0, pxls.Length); bmenc.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)cropBmp.PixelWidth, (uint)cropBmp.PixelHeight, originalPixelWidth, originalPixelHeight, pxls); await bmenc.FlushAsync(); /* var requestedMinSide = height; * var encoder = await BitmapEncoder.CreateForTranscodingAsync(irStream, decoder); * double widthRatio = (double)requestedMinSide / originalPixelWidth; * double heightRatio = (double)requestedMinSide / originalPixelHeight; * uint aspectHeight = (uint)requestedMinSide; * uint aspectWidth = (uint)requestedMinSide; * * bounds.Height = aspectHeight; * bounds.Width = aspectWidth; * * uint cropX = 0, cropY = 0; * var scaledSize = (uint)requestedMinSide; * 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 = bounds; * await encoder.FlushAsync();*/ } return(file); } }
// display image when last packet arrives private async void ProcessImageArr(byte[] img) // int imgType) { try { // Decode the JPEG MemoryStream stream = new MemoryStream(img); BitmapDecoder decoder = await BitmapDecoder.CreateAsync(BitmapDecoder.JpegDecoderId, stream.AsRandomAccessStream()); //PixelDataProvider pixelData = await decoder.GetPixelDataAsync(); //BitmapFrame frame = await decoder.GetFrameAsync(0); BitmapTransform bt = new BitmapTransform(); Debug.Log("Bitmap Frame and Transform Created"); PixelDataProvider pixelData = await decoder.GetPixelDataAsync(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Ignore, bt, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.DoNotColorManage); Debug.Log("Pixel Data Created. Format: " + decoder.BitmapPixelFormat); uint width = decoder.PixelWidth; uint height = decoder.PixelHeight; byte[] tmp = pixelData.DetachPixelData(); Debug.Log("Pixel Data Detached. Length: " + tmp.Length + ", Size: (" + width + ", " + height + ")"); //synthesize to one band byte[] tmpImgData = new byte[(int)width * (int)height]; //int[,] hist = {{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}; for (int i = 0; i < tmp.Length; i += 4) { /*for (int h = 0; h < 4; h++){ * if (tmp[i+h] <= 1*255/4) ++hist[h,0]; * else if (tmp[i+h] <= 2*255/4) ++hist[h,1]; * else if (tmp[i+h] <= 3*255/4) ++hist[h,2]; * else if (tmp[i+h] <= 4*255/4) ++hist[h,3]; * }*/ // turns out, reads greyscale image into RGB values, and 255 into A tmpImgData[i / 4] = tmp[i + 0]; //RGBAToByte(tmp[i + 0], tmp[i + 1], tmp[i + 2], tmp[i + 3]); } /*for (int h = 0; h < 4; h++) { * Debug.Log(string.Format("Hist {0}: <{1}, {2}, {3}, {4}>", h, hist[h,0], hist[h,1], hist[h,2], hist[h,3])); * }*/ lock (syncLock) { ID_NewImage = false; // unnecesary, but ensures cant be accessed while updating. lock (ID_ImageData1D) { ID_ImageWidth = (int)width; ID_ImageHeight = (int)height; ID_ImageData1D = tmpImgData; } ID_NewImage = true; ID_fps = 1.0 / (DateTime.Now.Subtract(time).TotalSeconds); time = DateTime.Now; } tmp = null; tmpImgData = null; } catch (Exception ex) { Debug.Log(ex.Message); } }
/// <summary> /// GetPixel /// </summary> /// <param name="bitmap"></param> /// <returns></returns> public async Task <byte[]> GetPixel(BitmapDecoder bitmap) { PixelDataProvider imagePixelData = await bitmap.GetPixelDataAsync(); return(imagePixelData.DetachPixelData()); }
public static async Task <SaveCoverImageResult> SaveAlbumCover(byte[] dataVector, string albumid) { SaveCoverImageResult result = null; var displayInformation = DisplayInformation.GetForCurrentView(); StorageFolder coversFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("Covers", CreationCollisionOption.OpenIfExists); string hexColor = string.Empty; SaveCoverImageResult.Result resultState; if (dataVector != null) { try { MemoryStream ms = new MemoryStream(dataVector); ms.Position = 0; StorageFile f = await coversFolder.CreateFileAsync("cover_" + albumid + ".jpg", CreationCollisionOption.ReplaceExisting); IRandomAccessStream ras = ms.AsRandomAccessStream(); BitmapDecoder decoder = await BitmapDecoder.CreateAsync(ras); double oldHeight = decoder.PixelHeight; double oldWidth = decoder.PixelWidth; double newWidth = 500; if (oldWidth < 500) { newWidth = oldWidth; } double newHeight = (oldHeight * newWidth) / oldWidth; BitmapTransform transform = new BitmapTransform() { ScaledWidth = (uint)newWidth, ScaledHeight = (uint)newHeight, InterpolationMode = BitmapInterpolationMode.NearestNeighbor }; PixelDataProvider pixelData = await decoder.GetPixelDataAsync( BitmapPixelFormat.Rgba8, BitmapAlphaMode.Ignore, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage); using (var destinationStream = await f.OpenAsync(FileAccessMode.ReadWrite)) { BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, destinationStream); encoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Premultiplied, (uint)newWidth, (uint)newHeight, displayInformation.RawDpiX, displayInformation.RawDpiY, pixelData.DetachPixelData()); await encoder.FlushAsync(); } hexColor = await ImageHelper.GetDominantColorHex(ras); ras.Dispose(); ms.Dispose(); resultState = SaveCoverImageResult.Result.Succeded; } catch { resultState = SaveCoverImageResult.Result.Failed; } } else { resultState = SaveCoverImageResult.Result.Failed; } result = new SaveCoverImageResult(hexColor, resultState); return(result); }
/// <summary> /// Recognize the text from handwriting using Microsoft Azure service. /// </summary> public async void RecognizeInking(IReadOnlyList <InkStroke> strokeList, double pageWidth, double pageHeight) { // Current bounding box for the strokes. double tlX = double.MaxValue; double tlY = double.MaxValue; double brX = 0; double brY = 0; inkingStatus = SERVICE_STATUS.PENDING; // Make a copy of this list List <InkStroke> newList = new List <InkStroke>(); foreach (InkStroke ss in strokeList) { newList.Add(ss); tlX = Math.Min(tlX, ss.BoundingRect.Left); tlY = Math.Min(tlY, ss.BoundingRect.Top); brX = Math.Max(brX, ss.BoundingRect.Right); brY = Math.Max(brY, ss.BoundingRect.Bottom); } double originalCroppedWidth = brX - tlX; double originalCroppedHeight = brY - tlY; // Create boundary tlX = Math.Max(0, tlX - originalCroppedWidth * 0.2); tlY = Math.Max(0, tlY - originalCroppedHeight * 0.4); brX = Math.Min(pageWidth, brX + originalCroppedWidth * 0.2); brY = Math.Min(pageHeight, brY + originalCroppedHeight * 0.4); originalCroppedWidth = brX - tlX; originalCroppedHeight = brY - tlY; StorageFolder storageFolder = KnownFolders.CameraRoll; var file = await storageFolder.CreateFileAsync("sampleInking.jpg", CreationCollisionOption.GenerateUniqueName); // Render a whole image (paper size * inking scale) CanvasDevice device = CanvasDevice.GetSharedDevice(); CanvasRenderTarget renderTarget = new CanvasRenderTarget(device, (float)pageWidth, (float)pageHeight, 96); //await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, // () => // { // using (var ds = renderTarget.CreateDrawingSession()) // { // ds.Clear(Colors.White); // ds.DrawInk(strokeList); // } // }); using (var ds = renderTarget.CreateDrawingSession()) { ds.Clear(Colors.White); ds.DrawInk(newList); } // Crop the image: using same algorithm as in OCR method. // croppedBytes: image bytes. // byteData: final format, with bmp header. byte[] byteData = new byte[1]; byte[] croppedBytes = new byte[1]; uint width = 0, height = 0; using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite)) { await renderTarget.SaveAsync(fileStream, CanvasBitmapFileFormat.Jpeg, 1f); //Debug.Log("Save to:" + file.Name); // Crop this image. // Create a decoder from the stream. With the decoder, we can get the properties of the image. BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream); // make sure the image is larger than 50x50 in real pixels. double scale = Math.Max(1.0f, Math.Max(AZURE_API_MIN_SIZE / originalCroppedWidth, AZURE_API_MIN_SIZE / originalCroppedHeight)); uint startPointX = (uint)Math.Floor(tlX * scale); uint startPointY = (uint)Math.Floor(tlY * scale); width = (uint)Math.Floor(originalCroppedWidth * scale); height = (uint)Math.Floor(originalCroppedHeight * scale); // The scaledSize of original image. uint scaledWidth = (uint)Math.Floor(decoder.PixelWidth * scale); uint scaledHeight = (uint)Math.Floor(decoder.PixelHeight * scale); // Refine the start point and the size. if (startPointX + width > scaledWidth) { startPointX = scaledWidth - width; } if (startPointY + height > scaledHeight) { startPointY = scaledHeight - height; } // Get the cropped pixels. BitmapTransform transform = new BitmapTransform(); BitmapBounds bounds = new BitmapBounds(); bounds.X = startPointX; bounds.Y = startPointY; bounds.Height = height; bounds.Width = width; transform.Bounds = bounds; transform.ScaledWidth = scaledWidth; transform.ScaledHeight = scaledHeight; // Get the cropped pixels within the bounds of transform. PixelDataProvider pix = await decoder.GetPixelDataAsync( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.ColorManageToSRgb); croppedBytes = pix.DetachPixelData(); //Debug.Log(string.Format("Crop Handwritten image: start: {0},{1}, width:{2}, height:{3}", bounds.X, bounds.Y, bounds.Width, bounds.Height)); } await file.DeleteAsync(); // Again, I have to save to file stream byte[] to image. // https://code.msdn.microsoft.com/windowsapps/How-to-save-WriteableBitmap-bd23d455 var tempFile = await storageFolder.CreateFileAsync("temp-sampleInking.jpg", CreationCollisionOption.GenerateUniqueName); using (var stream = await tempFile.OpenAsync(FileAccessMode.ReadWrite)) { BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream); encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, width, height, 96, 96, croppedBytes); await encoder.FlushAsync(); var reader = new DataReader(stream.GetInputStreamAt(0)); byteData = new byte[stream.Size]; await reader.LoadAsync((uint)stream.Size); reader.ReadBytes(byteData); } await tempFile.DeleteAsync(); //ReadHandwrittenText(""); HttpClient client = new HttpClient(); // Request headers. client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", azureKey); // Request parameter. Set "handwriting" to false for printed text. string requestParameters = "handwriting=true"; // Assemble the URI for the REST API Call. string uri = azureUri + "recognizeText?" + requestParameters; HttpResponseMessage response = null; // This operation requrires two REST API calls. One to submit the image for processing, // the other to retrieve the text found in the image. This value stores the REST API // location to call to retrieve the text. string operationLocation = null; // Request body. Posts a locally stored JPEG image. //byte[] byteData = canvasImg; ByteArrayContent content = new ByteArrayContent(byteData); // This example uses content type "application/octet-stream". // You can also use "application/json" and specify an image URL. content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); // The first REST call starts the async process to analyze the written text in the image. response = await client.PostAsync(uri, content); // The response contains the URI to retrieve the result of the process. if (response.IsSuccessStatusCode) { operationLocation = response.Headers.GetValues("Operation-Location").FirstOrDefault(); } else { // Display the JSON error data. string errInfo = "RecognizeInking: PosyAsync Response Error." + response.StatusCode.ToString(); inkingResult = errInfo; inkingStatus = SERVICE_STATUS.ERROR; Debug.Log(errInfo + "\n"); //Debug.Log(JsonPrettyPrint(await response.Content.ReadAsStringAsync())); return; } // The second REST call retrieves the text written in the image. // // Note: The response may not be immediately available. Handwriting recognition is an // async operation that can take a variable amount of time depending on the length // of the handwritten text. You may need to wait or retry this operation. // // This example checks once per second for ten seconds. string contentString; int i = 0; do { await Task.Delay(1000); response = await client.GetAsync(operationLocation); contentString = await response.Content.ReadAsStringAsync(); ++i; }while (i < 10 && contentString.IndexOf("\"status\":\"Succeeded\"") == -1); if (i == 10 && contentString.IndexOf("\"status\":\"Succeeded\"") == -1) { string errInfo = "RecognizeInking: Timeout Error."; inkingResult = errInfo; Debug.Log(errInfo + "\n"); inkingStatus = SERVICE_STATUS.ERROR; return; } // Display the JSON response. //Debug.Log("\nResponse:\n"); //Debug.Log(JsonPrettyPrint(contentString)); // Parse to output the result. var result = JsonConvert.DeserializeObject <JSONInking.RootObject>(contentString).recognitionResult; var texts = new List <string>(); foreach (var line in result.lines) { texts.Add(line.text); } if (texts.Count > 0) { inkingResult = string.Join(" ", texts); //Debug.Log("Inking Recognition succeeded:" + inkingResult); inkingStatus = SERVICE_STATUS.DONE; } else { string errInfo = "Inking Recognition succeeded but the result is empty."; inkingResult = errInfo; Debug.Log(errInfo); inkingStatus = SERVICE_STATUS.ERROR; } }