Created
February 28, 2010 17:49
-
-
Save martinbowling/317696 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ImageElement : Element { | |
// The original ImageElement didn't scale the picture that was displayed as the thumbnail properly | |
// this code probably needs lots of refactoring but I needed a quick solution. | |
public UIImage Value; | |
static RectangleF rect = new RectangleF (0, 0, dimx, dimy); | |
static NSString ikey = new NSString ("ikey"); | |
UIImage scaled; | |
// Apple leaks this one, so share across all. | |
static UIImagePickerController picker; | |
// Height for rows | |
const int dimx = 48; | |
const int dimy = 43; | |
// radius for rounding | |
const int rad = 10; | |
// pi for image rotation | |
const float M_PI = 3.141592653589793238462643f; | |
static UIImage MakeEmpty () | |
{ | |
using (var cs = CGColorSpace.CreateDeviceRGB ()){ | |
using (var bit = new CGBitmapContext (IntPtr.Zero, dimx, dimy, 8, 0, cs, CGImageAlphaInfo.PremultipliedFirst)){ | |
bit.SetRGBStrokeColor (1, 0, 0, 0.5f); | |
bit.FillRect (new RectangleF (0, 0, dimx, dimy)); | |
return UIImage.FromImage (bit.ToImage ()); | |
} | |
} | |
} | |
UIImage Scale (UIImage source) | |
{ | |
UIGraphics.BeginImageContext (new SizeF (dimx, dimy)); | |
var ctx = UIGraphics.GetCurrentContext (); | |
var img = source.CGImage; | |
ctx.TranslateCTM (0, dimy); | |
if (img.Width > img.Height) | |
ctx.ScaleCTM (1, -img.Width/dimy); | |
else | |
ctx.ScaleCTM (img.Height/dimx, -1); | |
ctx.DrawImage (rect, source.CGImage); | |
var ret = UIGraphics.GetImageFromCurrentImageContext (); | |
UIGraphics.EndImageContext (); | |
return ret; | |
} | |
UIImage Thumbnail (UIImage source) | |
{ | |
SizeF size = source.Size; | |
float offsetY = 0; | |
float offsetX = 0; | |
SizeF croppedSize; | |
// check the size of the image, we want to make it | |
// a square with sides the size of the smallest dimension | |
if (size.Width > size.Height) { | |
offsetX = (size.Height - size.Width) / 2; | |
croppedSize = new SizeF (size.Height, size.Height); | |
} else { | |
offsetY = (size.Width - size.Height) / 2; | |
croppedSize = new SizeF (size.Width, size.Width); | |
} | |
// Crop the image before resize | |
RectangleF clippedRect = new RectangleF (offsetX * -1 , offsetY * -1 , croppedSize.Width, croppedSize.Height); | |
UIImage cropped = UIImage.FromImage(source.CGImage.WithImageInRect(clippedRect)); | |
// Done cropping | |
UIGraphics.BeginImageContext (new SizeF (dimx, dimy)); | |
var ctx = UIGraphics.GetCurrentContext (); | |
ctx.DrawImage (rect, cropped.CGImage); | |
var ret = UIGraphics.GetImageFromCurrentImageContext (); | |
UIGraphics.EndImageContext (); | |
ret = FlipImage(ret); | |
return ret; | |
} | |
public UIImage FlipImage(UIImage source) | |
{ | |
UIGraphics.BeginImageContext (new SizeF (dimx, dimy)); | |
var ctx = UIGraphics.GetCurrentContext (); | |
ctx.DrawImage (rect, source.CGImage); | |
ctx.RotateCTM(M_PI); | |
var ret = UIGraphics.GetImageFromCurrentImageContext (); | |
UIGraphics.EndImageContext (); | |
return ret; | |
} | |
public ImageElement (UIImage image) : base ("") | |
{ | |
if (image == null){ | |
Value = MakeEmpty (); | |
scaled = Value; | |
} else { | |
Value = image; | |
scaled = Thumbnail(Value); | |
} | |
} | |
public override UITableViewCell GetCell (UITableView tv) | |
{ | |
var cell = tv.DequeueReusableCell (ikey); | |
if (cell == null){ | |
cell = new UITableViewCell (UITableViewCellStyle.Default, ikey); | |
} | |
if (scaled == null) | |
return cell; | |
Section psection = Parent as Section; | |
bool roundTop = psection.Elements [0] == this; | |
bool roundBottom = psection.Elements [psection.Elements.Count-1] == this; | |
using (var cs = CGColorSpace.CreateDeviceRGB ()){ | |
using (var bit = new CGBitmapContext (IntPtr.Zero, dimx, dimy, 8, 0, cs, CGImageAlphaInfo.PremultipliedFirst)){ | |
// Clipping path for the image, different on top, middle and bottom. | |
if (roundBottom){ | |
bit.AddArc (rad, rad, rad, (float) Math.PI, (float) (3*Math.PI/2), false); | |
} else { | |
bit.MoveTo (0, rad); | |
bit.AddLineToPoint (0, 0); | |
} | |
bit.AddLineToPoint (dimx, 0); | |
bit.AddLineToPoint (dimx, dimy); | |
if (roundTop){ | |
bit.AddArc (rad, dimy-rad, rad, (float) (Math.PI/2), (float) Math.PI, false); | |
bit.AddLineToPoint (0, rad); | |
} else { | |
bit.AddLineToPoint (0, dimy); | |
} | |
bit.Clip (); | |
bit.DrawImage (rect, scaled.CGImage); | |
cell.ImageView.Image = UIImage.FromImage (bit.ToImage ()); | |
cell.TextLabel.Text = "Add Photo"; | |
cell.Accessory = UITableViewCellAccessory.DisclosureIndicator; | |
} | |
} | |
return cell; | |
} | |
protected override void Dispose (bool disposing) | |
{ | |
if (disposing){ | |
scaled.Dispose (); | |
Value.Dispose (); | |
} | |
base.Dispose (disposing); | |
} | |
class MyDelegate : UIImagePickerControllerDelegate { | |
ImageElement container; | |
public MyDelegate (ImageElement container) | |
{ | |
this.container = container; | |
} | |
public override void FinishedPickingImage (UIImagePickerController picker, UIImage image, NSDictionary editingInfo) | |
{ | |
container.Picked (image); | |
} | |
} | |
void Picked (UIImage image) | |
{ | |
Value = image; | |
scaled = Thumbnail (image); | |
currentController.DismissModalViewControllerAnimated (true); | |
} | |
UIViewController currentController; | |
public override void Selected (DialogViewController dvc, UITableView tableView, NSIndexPath path) | |
{ | |
if (picker == null) | |
picker = new UIImagePickerController (); | |
picker.Delegate = new MyDelegate (this); | |
dvc.ActivateController (picker); | |
currentController = dvc; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment