public async Task<EnhanceResult> EnhanceAsync(Frame frame) { using (var bitmap = new Bitmap(new Windows.Foundation.Size(frame.Dimensions.Width, frame.Dimensions.Height), Internal.Utilities.FrameFormatToColorMode(frame.Format), frame.Pitch, frame.Buffer.AsBuffer())) using (var source = new BitmapImageSource(bitmap)) using (var effect = new FilterEffect(source)) using (var renderer = new BitmapRenderer(effect)) { effect.Filters = new List<IFilter>() { new ContrastFilter(0.5) }; using (var newBitmap = new Bitmap(new Windows.Foundation.Size(frame.Dimensions.Width, frame.Dimensions.Height), Internal.Utilities.FrameFormatToColorMode(frame.Format))) { await effect.GetBitmapAsync(newBitmap, OutputOption.PreserveAspectRatio); return new EnhanceResult() { Frame = new Frame() { Buffer = newBitmap.Buffers[0].Buffer.ToArray(), Pitch = newBitmap.Buffers[0].Pitch, Format = frame.Format, Dimensions = newBitmap.Dimensions } }; } } }
public async Task<NormalizeResult> NormalizeAsync(Frame frame, Windows.Foundation.Rect area, double rotation) { using (var bitmap = new Bitmap(frame.Dimensions, Internal.Utilities.FrameFormatToColorMode(frame.Format), frame.Pitch, frame.Buffer.AsBuffer())) using (var source = new BitmapImageSource(bitmap)) using (var effect = new FilterEffect(source)) using (var renderer = new BitmapRenderer(effect)) { effect.Filters = new List<IFilter>() { new ReframingFilter(area, -rotation) }; using (var newBitmap = new Bitmap(new Windows.Foundation.Size(area.Width, area.Height), Internal.Utilities.FrameFormatToColorMode(frame.Format))) { await effect.GetBitmapAsync(newBitmap, OutputOption.PreserveAspectRatio); return new NormalizeResult() { Frame = new Frame() { Buffer = newBitmap.Buffers[0].Buffer.ToArray(), Pitch = newBitmap.Buffers[0].Pitch, Format = frame.Format, Dimensions = newBitmap.Dimensions }, Translate = new Func<Windows.Foundation.Point, Windows.Foundation.Point>((normalizedPoint) => { var rotationRadians = -rotation / 360.0 * 2.0 * Math.PI; var sin = Math.Sin(rotationRadians); var cos = Math.Cos(rotationRadians); var origoX = area.Width / 2.0; var origoY = area.Height / 2.0; // Translate point to origo before rotation var ox = normalizedPoint.X - origoX; var oy = normalizedPoint.Y - origoY; // Move area to origo, calculate new point positions, restore area location and add crop margins var x = ox * cos - oy * sin; var y = ox * sin + oy * cos; // Translate point back to area after rotation x = x + origoX; y = y + origoY; // Add margins from original uncropped frame x = x + area.X; y = y + area.Y; return new Windows.Foundation.Point(x, y); }) }; } } }
public async Task<DecodeResult> DecodeAsync(Frame frame) { var result = await Task.Run<ZXing.Result>(() => { var width = 0; if (frame.Format == FrameFormat.Bgra32) { width = (int)frame.Dimensions.Width; } else if (frame.Format == FrameFormat.Gray8) { width = (int)frame.Pitch; } else { throw new ArgumentException(String.Format("Incompatible frame format: {0}", frame.Format.ToString())); } return _reader.Decode(frame.Buffer, width, (int)frame.Dimensions.Height, FrameFormatToBitmapFormat(frame.Format)); }); if (result != null) { var decodeResult = new DecodeResult() { Text = result.Text, Data = result.RawBytes, Format = result.BarcodeFormat.ToString() }; if (result.ResultPoints != null && result.ResultPoints.Length > 0) { decodeResult.InterestPoints = new List<Windows.Foundation.Point>(); foreach (ZXing.ResultPoint point in result.ResultPoints) { decodeResult.InterestPoints.Add(new Windows.Foundation.Point(point.X, point.Y)); } } return decodeResult; } else { return null; } }
public virtual async Task<ProcessResult> ProcessAsync(Frame frame, Windows.Foundation.Rect area, double rotation) { var timedExecution = new Internal.TimedExecution(); var normalizeTime = new TimeSpan(0); var enhanceTime = new TimeSpan(0); var decodeTime = new TimeSpan(0); NormalizeResult normalizeResult = null; if (Normalizer != null) { normalizeResult = await timedExecution.ExecuteAsync<NormalizeResult>( Normalizer.NormalizeAsync(frame, area, rotation).AsAsyncOperation()); normalizeTime = timedExecution.ExecutionTime; frame = normalizeResult.Frame; } if (Enhancer != null) { var enhanceResult = await timedExecution.ExecuteAsync<EnhanceResult>( Enhancer.EnhanceAsync(frame).AsAsyncOperation()); enhanceTime = timedExecution.ExecutionTime; frame = enhanceResult.Frame; } var decodeResult = await timedExecution.ExecuteAsync<DecodeResult>( Decoder.DecodeAsync(frame).AsAsyncOperation()); decodeTime = timedExecution.ExecutionTime; #if DEBUG System.Diagnostics.Debug.WriteLine(String.Format( "Normalizing took {0} ms, enhancing took {1} ms, decoding took {2}, which totals to {3} ms", (int)normalizeTime.TotalMilliseconds, (int)enhanceTime.TotalMilliseconds, (int)decodeTime.TotalMilliseconds, (int)(normalizeTime + enhanceTime + decodeTime).TotalMilliseconds)); #endif // DEBUG if (DebugFrameAvailable != null) { DebugFrameAvailable(this, new DebugFrameEventArgs() { DebugFrame = frame }); } if (decodeResult != null) { var interestPoints = decodeResult.InterestPoints; if (interestPoints != null) { if (normalizeResult != null && normalizeResult.Translate != null) { var translatedInterestPoints = new List<Windows.Foundation.Point>(); foreach (var point in interestPoints) { translatedInterestPoints.Add(normalizeResult.Translate(point)); } interestPoints = translatedInterestPoints; } } return new ProcessResult() { Data = decodeResult.Data, Format = decodeResult.Format, Text = decodeResult.Text, InterestPoints = interestPoints }; } else { return null; } }