Get UIImage from captured CMSampleBufferPosted in Apps on May 12, 2011 by Pavel Sich When working with the video capture, the image buffer is not usually enough and we need to pick up the UIImage from the buffer. UIImage ImageFromSampleBuffer (CMSampleBuffer sampleBuffer) { // Get the CoreVideo image using (var pixelBuffer = sampleBuffer.GetImageBuffer () as CVPixelBuffer){ // Lock the base address pixelBuffer.Lock (0); // Get the number of bytes per row for the pixel buffer var baseAddress = pixelBuffer.BaseAddress; int bytesPerRow = pixelBuffer.BytesPerRow; int width = pixelBuffer.Width; int height = pixelBuffer.Height; var flags = CGBitmapFlags.PremultipliedFirst | CGBitmapFlags.ByteOrder32Little; // Create a CGImage on the RGB colorspace from the configured parameter above using (var cs = CGColorSpace.CreateDeviceRGB ()) using (var context = new CGBitmapContext (baseAddress,width, height, 8, bytesPerRow, cs, (CGImageAlphaInfo) flags)) using (var cgImage = context.ToImage ()){ pixelBuffer.Unlock (0); return UIImage.FromImage (cgImage); } } }
Convert time in UIDatePicker to localPosted in Apps on May 09, 2011 by Pavel Sich When working with UIDatePicker time mode, it is typical that the time is picked in UTC and it needs to be converted to the local time and DateTime representation for purposes of showing it, setting up an alarm and such.
NSDate sourceDate = picker.Date; NSTimeZone sourceTimeZone = new NSTimeZone ("UTC"); NSTimeZone destinationTimeZone = NSTimeZone.LocalTimeZone; int sourceGMTOffset = sourceTimeZone.SecondsFromGMT (sourceDate); int destinationGMTOffset = destinationTimeZone.SecondsFromGMT (sourceDate); int interval = destinationGMTOffset - sourceGMTOffset; var destinationDate = sourceDate.AddSeconds (interval); var dateTime = new DateTime(2001, 1, 1, 0, 0, 0).AddSeconds(destinationDate.SecondsSinceReferenceDate); Happy coding!
Custom PageControlPosted in Apps on May 09, 2011 by Pavel Sich The standard UIPageControl does not allow custom sizes and colors for the page indicators. This is an implementation that fixes that.
using System; using System.Drawing; using MonoTouch.Foundation; using MonoTouch.UIKit; using MonoTouch.CoreGraphics; namespace MonoTouch.UIKit.Extensions { public enum PageControlType { OnFullOffFull, OnFullOffEmpty, OnEmptyOffFull, OnEmptyOffEmpty } public class PageControl : UIControl { private int numberOfPages; public int Pages { get { return numberOfPages; } set { // make sure the number of pages is positive numberOfPages = Math.Max(0, value); // we then need to update the current page currentPage = Math.Min(Math.Max(0, currentPage), numberOfPages - 1); // correct the bounds accordingly this.Bounds = this.Bounds; // we need to redraw this.SetNeedsDisplay (); // depending on the user preferences, we hide the page control with a single element if (HidesForSinglePage && (numberOfPages < 2)) this.Hidden = true; else this.Hidden = false; } } private int currentPage; public int CurrentPage { get { return currentPage; } set { // no need to update in that case if (currentPage == value) return; // determine if the page number is in the available range currentPage = Math.Min(Math.Max(0, value), numberOfPages - 1); this.SetNeedsDisplay (); } } private bool hidesForSinglePage; public bool HidesForSinglePage { get { return hidesForSinglePage; } set { hidesForSinglePage = value; // depending on the user preferences, we hide the page control with a single element if (hidesForSinglePage && (numberOfPages < 2)) this.Hidden = true; } } public bool DefersCurrentPageDisplay { get; set; } public PageControlType ControlType { get; set; } public UIColor OnColor { get; set; } public UIColor OffColor { get; set; } public float IndicatorDiameter { get; set; } public float IndicatorSpace { get; set; } private const float kDotDiameter = 4.0f; private const float kDotSpace = 12.0f; /// <summary> /// Initializes a new instance of the <see cref="ieMobile.PageControl"/> class. /// </summary> /// <param name='ct'> /// Ct. /// </param> /// <param name='frame'> /// Frame. /// </param> public PageControl (PageControlType ct, RectangleF rect) : base (rect) { ControlType = ct; DefersCurrentPageDisplay = false; this.BackgroundColor = UIColor.Clear; } /// <summary> /// Sizes for number of pages. /// </summary> /// <returns> /// The for number of pages. /// </returns> /// <param name='pageCount'> /// Page count. /// </param> public SizeF SizeForNumberOfPages (int pageCount) { float diameter = (IndicatorDiameter > 0) ? IndicatorDiameter : kDotDiameter; float space = (IndicatorSpace > 0) ? IndicatorSpace : kDotSpace; return new SizeF(pageCount * diameter + (pageCount - 1) * space + 44.0f, Math.Max(44.0f, diameter + 4.0f)); } /// <summary> /// Draws the rect. /// </summary> /// <param name='area'> /// Area. /// </param> /// <param name='formatter'> /// Formatter. /// </param> public override void Draw (RectangleF area) { base.Draw (area); // get the current context CGContext context = UIGraphics.GetCurrentContext (); // save the context context.SaveState (); // allow antialiasing context.SetAllowsAntialiasing (true); // get the caller's diameter if it has been set or use the default one float diameter = (IndicatorDiameter > 0) ? IndicatorDiameter : kDotDiameter; float space = (IndicatorSpace > 0) ? IndicatorSpace : kDotSpace; // geometry RectangleF currentBounds = this.Bounds; float dotsWidth = this.Pages * diameter + Math.Max(0, this.Pages - 1) * space; float x = currentBounds.GetMidX () - dotsWidth / 2; float y = currentBounds.GetMidY () - diameter / 2; // get the caller's colors it they have been set or use the defaults CGColor onColorCG = OnColor != null ? OnColor.CGColor : UIColor.FromWhiteAlpha(1.0f, 1.0f).CGColor; CGColor offColorCG = OffColor != null ? OffColor.CGColor : UIColor.FromWhiteAlpha(0.7f, 0.5f).CGColor; // actually draw the dots for (int i = 0; i < Pages; i++) { RectangleF dotRect = new RectangleF (x, y, diameter, diameter); if (i == CurrentPage) { if (ControlType == PageControlType.OnFullOffFull || ControlType == PageControlType.OnFullOffEmpty) { context.SetFillColorWithColor (onColorCG); context.FillEllipseInRect(dotRect.Inset (-1.0f, -1.0f)); } else { context.SetStrokeColorWithColor (onColorCG); context.StrokeEllipseInRect (dotRect); } } else { if (ControlType == PageControlType.OnEmptyOffEmpty || ControlType == PageControlType.OnFullOffEmpty) { context.SetStrokeColorWithColor (offColorCG); context.StrokeEllipseInRect (dotRect); } else { context.SetFillColorWithColor (offColorCG); context.FillEllipseInRect (dotRect.Inset (-1.0f, -1.0f)); } } x += diameter + space; } // restore the context context.RestoreState (); } /// <summary> /// Toucheses the ended. /// </summary> /// <param name='touches'> /// Touches. /// </param> /// <param name='evt'> /// Evt. /// </param> public override void TouchesEnded (NSSet touches, UIEvent evt) { base.TouchesEnded (touches, evt); // get the touch location UITouch theTouch = touches.AnyObject as UITouch; PointF touchLocation = theTouch.LocationInView (this); // check whether the touch is in the right or left hand-side of the control if (touchLocation.X < (this.Bounds.Size.Width / 2)) this.CurrentPage = Math.Max(this.CurrentPage - 1, 0) ; else this.CurrentPage = Math.Min(this.CurrentPage + 1, Pages - 1) ; // send the value changed action to the target this.SendActionForControlEvents (UIControlEvent.ValueChanged); } } }
Usage is pretty simple.
var pageControl = new PageControl (PageControlType.OnFullOffFull, rectanglePosition); pageControl.OnColor = UIColor.Blue; pageControl.OffColor = UIColor.DarkGray; pageControl.Pages = num of pages; Happy coding!
iOS SDK cannot installPosted in Apps on September 24, 2010 by Pavel Sich Ever had the problem installing any mpkg installer? Happened to me today, I received for no apparent reason information that JavaScript check failed during the iOS SDK installation. Was not able to resolve in a normal way, so had to hack a bit, here it is how (BTW works for any mpkg file, not only Xcode with iOS SDK). 1. extract the mpkg package with XAR (xar -xf path_to_your_installer.mpkg) function volumeCheck() { return true; } 5. close the text edit and save the file BTW. if you use PathFinder app you can save lots of manual work, just right click the MPKG, select show content, then click the dist file and select open with and edit it in place. save it and that is it, PathFinder will repackage for you. Happy hacking (in this case).
Spiders get into an iPhone and are building webs!Posted in Apps on September 14, 2010 by Pavel Mikunda
Learn more at http://www.touch4apps.com
|
