Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save martinbowling/317696 to your computer and use it in GitHub Desktop.
Save martinbowling/317696 to your computer and use it in GitHub Desktop.
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