private NSValue ToCASkewTransform(float angleX, float angleY) { var matrix = CGAffineTransform.MakeIdentity(); matrix.yx = (float)Math.Tan(MathEx.ToRadians(angleY)); matrix.xy = (float)Math.Tan(MathEx.ToRadians(angleX)); return(NSValue.FromCATransform3D(CATransform3D.MakeFromAffine(matrix))); }
// An AutoResetEvent instance is used for drawing metadata object overlays so that // only one group of metadata object overlays is drawn at a time. MetadataObjectLayer CreateMetadataOverlay(AVMetadataObject metadataObject) { // Transform the metadata object so the bounds are updated to reflect those of the video preview layer. var transformedMetadataObject = PreviewView.VideoPreviewLayer.GetTransformedMetadataObject(metadataObject); // Create the initial metadata object overlay layer that can be used for either machine readable codes or faces. var metadataObjectOverlayLayer = new MetadataObjectLayer { MetadataObject = transformedMetadataObject, LineJoin = CAShapeLayer.JoinRound, LineWidth = 7, StrokeColor = View.TintColor.ColorWithAlpha(0.7f).CGColor, FillColor = View.TintColor.ColorWithAlpha(0.3f).CGColor }; var barcodeMetadataObject = transformedMetadataObject as AVMetadataMachineReadableCodeObject; if (barcodeMetadataObject != null) { var barcodeOverlayPath = BarcodeOverlayPathWithCorners(barcodeMetadataObject.Corners); metadataObjectOverlayLayer.Path = barcodeOverlayPath; // If the metadata object has a string value, display it. if (barcodeMetadataObject.StringValue.Length > 0) { var barcodeOverlayBoundingBox = barcodeOverlayPath.BoundingBox; var font = UIFont.BoldSystemFontOfSize(19).ToCTFont(); var textLayer = new CATextLayer { AlignmentMode = CATextLayer.AlignmentCenter, Bounds = new CGRect(0, 0, barcodeOverlayBoundingBox.Size.Width, barcodeOverlayBoundingBox.Size.Height), ContentsScale = UIScreen.MainScreen.Scale, Position = new CGPoint(barcodeOverlayBoundingBox.GetMidX(), barcodeOverlayBoundingBox.GetMidY()), Wrapped = true, // Invert the effect of transform of the video preview so the text is orientated with the interface orientation. Transform = CATransform3D.MakeFromAffine(PreviewView.Transform).Invert(default(CATransform3D)), AttributedString = new NSAttributedString(barcodeMetadataObject.StringValue, new CTStringAttributes { Font = font, ForegroundColor = UIColor.White.CGColor, StrokeWidth = -5, StrokeColor = UIColor.Black.CGColor }) }; textLayer.SetFont(font); metadataObjectOverlayLayer.AddSublayer(textLayer); } } else if (transformedMetadataObject is AVMetadataFaceObject) { metadataObjectOverlayLayer.Path = CGPath.FromRect(transformedMetadataObject.Bounds); } return(metadataObjectOverlayLayer); }
void SetupLayers() { if (view == null || view.Bounds.Size.IsEmpty) { return; } RemoveLayers(); var shear = new CGAffineTransform(1.0f, 0, shearFactor, 1.0f, 0.0f, 0.0f); // replicator layer replicatorLayer = new CAReplicatorLayer(); replicatorLayer.BackgroundColor = trackColor.CGColor; replicatorLayer.Frame = view.Bounds; replicatorLayer.InstanceCount = (nint)(1 + view.Bounds.Width / hatchSize); replicatorLayer.PreservesDepth = false; replicatorLayer.InstanceTransform = CATransform3D.MakeTranslation((nfloat)(hatchSize * 2.0), 0, 0); if (view.Layer == null) { view.Layer = new CALayer(); } view.Layer.AddSublayer(replicatorLayer); view.WantsLayer = true; // instance layer var layerHeight = view.Bounds.Height; var layerWidth = hatchSize; var instanceLayer = new CALayer(); instanceLayer.Frame = new CGRect(0, 0, layerWidth, layerHeight); instanceLayer.BackgroundColor = hatchColor.CGColor; instanceLayer.Bounds = new CGRect(0, 0, layerWidth, layerHeight); instanceLayer.Transform = CATransform3D.MakeFromAffine(shear); replicatorLayer.AddSublayer(instanceLayer); var runAnimation = CABasicAnimation.FromKeyPath("transform.translation.x"); runAnimation.From = NSNumber.FromDouble(-hatchSize); runAnimation.To = NSNumber.FromDouble(hatchSize); runAnimation.Duration = 0.5; runAnimation.RepeatCount = float.PositiveInfinity; instanceLayer.AddAnimation(runAnimation, "RunAnimation"); }
//partial void SelectMetadataObjectTypes(UIButton sender) //{ // var controller = new ItemSelectionViewController<AVMetadataObjectType>(this, // MetadataObjectTypeItemSelectionIdentifier, // this.metadataOutput.AvailableMetadataObjectTypes.GetFlags().ToList(), // this.metadataOutput.MetadataObjectTypes.GetFlags().ToList(), // true); // this.PresentItemSelectionViewController(controller); //} /// <summary> /// 2.스캔결과값 /// </summary> /// <param name="metadataObject"></param> /// <returns></returns> private MetadataObjectLayer CreateMetadataOverlay(AVMetadataObject metadataObject) { // Transform the metadata object so the bounds are updated to reflect those of the video preview layer. var transformedMetadataObject = this.PreviewView.VideoPreviewLayer.GetTransformedMetadataObject(metadataObject); // Create the initial metadata object overlay layer that can be used for either machine readable codes or faces. //빔 컬러 var metadataObjectOverlayLayer = new MetadataObjectLayer { LineWidth = 3, LineJoin = CAShapeLayer.JoinRound, MetadataObject = transformedMetadataObject, FillColor = UIColor.Red.CGColor, StrokeColor = UIColor.Red.CGColor //FillColor = this.View.TintColor.ColorWithAlpha(0.3f).CGColor, //StrokeColor = this.View.TintColor.ColorWithAlpha(0.7f).CGColor }; var barcodeMetadataObject = transformedMetadataObject as AVMetadataMachineReadableCodeObject; if (barcodeMetadataObject != null) { var barcodeOverlayPath = this.BarcodeOverlayPathWithCorners(barcodeMetadataObject.Corners); metadataObjectOverlayLayer.Path = barcodeOverlayPath; // If the metadata object has a string value, display it. string textLayerString = null; //스캔된 바코드 값 //바코드 타입 : barcodeMetadataObject.Type if (!string.IsNullOrEmpty(barcodeMetadataObject.StringValue)) { textLayerString = barcodeMetadataObject.StringValue; } else { // TODO: add Descriptor (line 618 in original iOS sample) } //스캔된 바코드 값 if (!string.IsNullOrEmpty(textLayerString)) { Console.WriteLine("========Result========"); Console.WriteLine(barcodeMetadataObject.Type + ", " + barcodeMetadataObject.StringValue); //this.PreviewView.customOverlay.tableSource.tableItems.Add(new TableItem { Heading = "heading", SubHeading = "subheading", ImageName = "barcode36x36.png" }); //this.InvokeOnMainThread(() => { this.PreviewView.customOverlay.RowAdd("aa", "bb"); }); var barcodeOverlayBoundingBox = barcodeOverlayPath.BoundingBox; var font = UIFont.BoldSystemFontOfSize(16).ToCTFont(); var textLayer = new CATextLayer(); textLayer.TextAlignmentMode = CATextLayerAlignmentMode.Center; //글자표시 박스, 높이가 작아서 글자 안보임 +50추가 textLayer.Bounds = new CGRect(0, 0, barcodeOverlayBoundingBox.Size.Width + 20, barcodeOverlayBoundingBox.Size.Height + 50); //textLayer.Bounds = new CGRect(0, 0, 300, 100); textLayer.ContentsScale = UIScreen.MainScreen.Scale; textLayer.Position = new CGPoint(barcodeOverlayBoundingBox.GetMidX(), barcodeOverlayBoundingBox.GetMidY()); textLayer.Wrapped = true; textLayer.Transform = CATransform3D.MakeFromAffine(this.PreviewView.Transform).Invert(); //------------------------------------- //스캔된 바코드 biz logic //------------------------------------- //연속 스캔 if (this.IsContinue) { if (this.IsFixed) { if (this.AllScanBarcode.Contains(textLayerString)) { //1. 저장 했는지? if (this.SaveCompletedBarcode.Contains(textLayerString)) { //저장 완료 //Color.Green textLayer.String = "저장 완료\n" + textLayerString; textLayer.AttributedString = new NSAttributedString(textLayer.String, new CTStringAttributes { Font = font, StrokeWidth = 0, StrokeColor = UIColor.Black.CGColor, ForegroundColor = UIColor.Green.CGColor }); //경고 audioCautionPlayer.Play(); doubleVibrator.PlaySystemSoundAsync(); } //2. Scan 완료 했는지? else if (this.ScanCompletedBarcode.Contains(textLayerString)) { //스캔 완료 //Color.Yellow textLayer.String = "스캔 완료\n" + textLayerString; textLayer.AttributedString = new NSAttributedString(textLayer.String, new CTStringAttributes { Font = font, StrokeWidth = 0, StrokeColor = UIColor.Black.CGColor, ForegroundColor = UIColor.Yellow.CGColor }); //경고 audioCautionPlayer.Play(); doubleVibrator.PlaySystemSoundAsync(); } else { //------------ //정상처리 작업 //------------ OnScanCompleted?.Invoke(barcodeMetadataObject.Type.ToString(), textLayerString); textLayer.String = textLayerString; textLayer.AttributedString = new NSAttributedString(textLayer.String, new CTStringAttributes { Font = font, StrokeWidth = 0, StrokeColor = UIColor.Black.CGColor, ForegroundColor = UIColor.White.CGColor }); //정상 audioPlayer.Play(); SystemSound.Vibrate.PlaySystemSoundAsync(); if (!this.ScanCompletedBarcode.Contains(textLayerString)) { this.ScanCompletedBarcode.Add(textLayerString); } if (this.AllScanBarcode.Count == this.SaveCompletedBarcode.Count + this.ScanCompletedBarcode.Count) { this.session.StopRunning(); OnScanCompleted?.Invoke(string.Empty, "EXIT"); DismissViewController(true, null); //화면 종료 } else { //연속스캔 사이의 간격 지정 //이 함수 호출하는 부분에서 처리 } } } else { //스캔 대상X //Color.Red textLayer.String = "스캔 대상X\n" + textLayerString; textLayer.AttributedString = new NSAttributedString(textLayer.String, new CTStringAttributes { Font = font, StrokeWidth = 0, StrokeColor = UIColor.Black.CGColor, ForegroundColor = UIColor.Red.CGColor }); //경고 audioCautionPlayer.Play(); doubleVibrator.PlaySystemSoundAsync(); } } //비고정(스캔 대상 없음) else { //현재로서는 biz로직 없음 } } //단일 스캔 else { this.session.StopRunning(); textLayer.String = textLayerString; textLayer.AttributedString = new NSAttributedString(textLayer.String, new CTStringAttributes { Font = font, StrokeWidth = 0, StrokeColor = UIColor.Black.CGColor, ForegroundColor = UIColor.White.CGColor }); //정상 audioPlayer.Play(); SystemSound.Vibrate.PlaySystemSoundAsync(); OnScanCompleted?.Invoke(barcodeMetadataObject.Type.ToString(), textLayerString); DismissViewController(true, null); //화면 종료 } //화면에 표시 textLayer.SetFont(font); metadataObjectOverlayLayer.AddSublayer(textLayer); } } else if (transformedMetadataObject is AVMetadataFaceObject) { metadataObjectOverlayLayer.Path = CGPath.FromRect(transformedMetadataObject.Bounds); } return(metadataObjectOverlayLayer); }
internal static void pulseExpandAnimation(CALayer layer, CALayer visualLayer, CGPoint point, nfloat width, nfloat height, Pulse pulse) { if (pulse.Animation != PulseAnimation.None) { nfloat n = pulse.Animation == PulseAnimation.Center ? width < height ? width : height : width < height ? height : width; var bLayer = new CAShapeLayer(); var pLayer = new CAShapeLayer(); bLayer.AddSublayer(pLayer); pulse.Layers.Enqueue(bLayer); visualLayer.AddSublayer(bLayer); Animation.AnimationDisabled(() => { bLayer.Frame = visualLayer.Bounds; pLayer.Bounds = new CGRect(0, 0, n, n); switch (pulse.Animation) { case PulseAnimation.Center: case PulseAnimation.CenterWithBacking: case PulseAnimation.CenterRadialBeyondBounds: pLayer.Position = new CGPoint(width / 2, height / 2); break; default: pLayer.Position = point; break; } pLayer.CornerRadius = n / 2; pLayer.BackgroundColor = pulse.Color.ColorWithAlpha(pulse.Opacity).CGColor; pLayer.Transform = CATransform3D.MakeFromAffine(CGAffineTransform.MakeScale(0, 0)); }); bLayer.SetValueForKey(NSObject.FromObject(false), new NSString("animated")); var duration = pulse.Animation == PulseAnimation.Center ? 0.16125 : 0.325; switch (pulse.Animation) { case PulseAnimation.CenterWithBacking: case PulseAnimation.Backing: case PulseAnimation.AtPointWithBacking: bLayer.AddAnimation(Animation.BackgroundColor(pulse.Color.ColorWithAlpha(pulse.Opacity / 2), duration), null); break; default: break; } switch (pulse.Animation) { case PulseAnimation.Center: case PulseAnimation.CenterWithBacking: case PulseAnimation.CenterRadialBeyondBounds: case PulseAnimation.AtPoint: case PulseAnimation.AtPointWithBacking: pLayer.AddAnimation(Animation.Scale(1, duration), null); break; default: break; } Animation.Delay(duration, () => { bLayer.SetValueForKey(NSObject.FromObject(true), new NSString("animated")); }); } }