What does CGPointApplyAffineTransform translate into in Monotouch? - xamarin.ios

I'm missing CGPointApplyAffineTransform(CGPoint, CGAffineTransform) in Monotouch.
Any ideas how to convert this?

CGPointApplyAffineTransform should map to:
public PointF MonoTouch.CoreGraphics.CGAffineTransform.TransformPoint (PointF point);

Example:
CGPoint newPoint = new CGPoint (0, 0);
newPoint = View.Transform.TransformPoint(newPoint);

Related

How to draw a straight line in Xamarin?

How to draw a straight line on imageview in Xamarin using c#. I have to draw the straight line and calculate length of that line.
Please help me. Thanks in advance..
You can extend UIImageView and inside a method draw a line like so:
public void DrawLine()
{
CGContext context = UIGraphics.GetCurrentContext ();
context.SetLineWidth (4);
UIColor.Clear.SetFill ();
UIColor.Black.SetStroke ();
currentPath = new CGPath ();
currentPath.AddLines (points.ToArray());
context.AddPath (currentPath);
context.DrawPath (CGPathDrawingMode.Stroke);
context.SaveState ();
}
points is a List of PointF objects.

CALayer as SubLayer Not Visible

I am trying to built an animated circle which would be drawn clockwise until it becomes complete circle as illustrated in iPhone Core Animation - Drawing a Circle
Problem is that CALayer object is not added or build. I tested and saw that it is not accessing my drawInContext:CGContextRef and animatingArc methods.
What so far I have done is:
In AnimateArc.h
#interface AnimateArc : CALayer {
CAShapeLayer *circle;
}
-(void) animatingArc;
#end
In AnimateArc.m
-(void) drawInContext:(CGContextRef)ctx
{
CGFloat radius = 50.0;
circle = [CAShapeLayer layer];
//make a circular shape
circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0.0, 0.0, 2 * radius, 2 * radius) cornerRadius:radius].CGPath;
CGPoint centerPoint = CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2);
//center the shape in self.view
circle.position = centerPoint;
//configure appearence of circle
circle.fillColor = [UIColor clearColor].CGColor;
circle.strokeColor = [UIColor blackColor].CGColor;
circle.lineWidth = 5;
/*CGPointMake((self.contentsCenter.size.width), (self.contentsCenter.size.height));*/
//path the circle
CGContextAddArc(ctx, centerPoint.x, centerPoint.y, radius, 0.0, 2 * M_PI, 0);
CGContextClosePath(ctx);
//fill it
CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
CGContextFillPath(ctx); }
///////////////////////////////////////////////////////////////////////
-(void) animatingArc
{
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:#"arcEnd"];
anim.duration = 20.0; //animate over 20 seconds
anim.repeatCount = 1.0; //animate only once
anim.removedOnCompletion = NO; //Reamin there after completion
//animate from start to end
anim.fromValue = [NSNumber numberWithFloat:50.0f];
anim.toValue = [NSNumber numberWithFloat:150.0f];
//experiment with timing to get appearence to look the way you want
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
//add animation to circle
[circle addAnimation:anim forKey:#"animatingArc"];
}
/////////////////////
//needed since key not part of animatable properties
+(BOOL) needsDisplayForKey:(NSString *)key
{
if([key isEqualToString:#"arcEnd"])
return YES;
else
return [super needsDisplayForKey:key];
}
//ensure custom properties copied to presentation layer
-(id) initWithLayer:(id)layer
{
if((self = [super initWithLayer:layer]))
{
if ([layer isKindOfClass:[AnimateArc class]])
{
AnimateArc *other = (AnimateArc *) layer;
[other setNeedsDisplay];
}
}
return self; }
And finally in my viewController,
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view.layer addSublayer:AnimateArcObject];
[AnimateArcObject animatingArc];
}
Apology for bad formatting.... Please can someone tell me what am I doing wrong? I have also doubt that my code can crash at any place after accessing those two functions since I am novice about Core Animation and haven't got any idea that I am in right direction or not.
Any help will be appreciated. Thanks.
From my painful experience with CoreAnimation, you must always set the bounds property of any CALayer you instantiate.
So, you're layer is not showing because you are missing something like:
layer.bounds = CGRectMake(0, 0, width, height);
you should place this as soon as you instantiate the layer, and make it a habit to do so, so you don't fall into it again.
As for your code crashing, sorry. It's too distributed and I am not sure how it's linked together, so I can't help you there.
After little searching, I thought that I am going in wrong direction. So I deleted this AnimateArc file and added new one which is inheriting from UIViewController.
Then in viewDidLoad Method, I wrote the code from this link to create circle and animations using path.
In parent view controller, I added AnimatedArc ViewController's subview. Now its working perfectly :)

Cannot fill CGContext for simple shape

The following method should create a FILLED triangle image but it only creates an outline.
Why does it not FILL? Going bonkers with this one. I hope it gets answered so that the next poor soul struggling with this can clear the hurdle and save an hour of their life.
Here is the method I wrote:
+ (UIImage *)triangleWithSize:(CGSize)imageSize
{
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetShouldAntialias(context, YES);
// set parameters
CGContextSetLineWidth(context, 1);
CGContextSetStrokeColorWithColor(context, [UIColor yellowColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor yellowColor].CGColor);
// draw triangle
CGContextBeginPath(context);
CGContextMoveToPoint(context, imageSize.width, 0);
CGContextAddLineToPoint(context, imageSize.width, imageSize.height);
CGContextMoveToPoint(context, imageSize.width, imageSize.height);
CGContextAddLineToPoint(context, 0, imageSize.height / 2);
CGContextMoveToPoint(context, 0, imageSize.height / 2);
CGContextAddLineToPoint(context, imageSize.width, 0);
// CGContextFillPath(context);
// CGContextClosePath(context);
// stroke and fill?
CGContextDrawPath(context, kCGPathFillStroke);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsPopContext();
return image;
}
Any help is appreciated.
I found the answer from the following post:
CGContext line drawing: CGContextFillPath not working?
One of the last answers provides an example using CGMutablePathRef. For a triangle, I used the following code:
CGMutablePathRef pathRef = CGPathCreateMutable();
CGPathMoveToPoint(pathRef, NULL, imageSize.width, 0);
CGPathAddLineToPoint(pathRef, NULL, imageSize.width, imageSize.height);
CGPathAddLineToPoint(pathRef, NULL, 0, imageSize.height / 2);
CGPathAddLineToPoint(pathRef, NULL, imageSize.width, 0);
CGPathCloseSubpath(pathRef);
CGContextAddPath(context, pathRef);
CGContextFillPath(context);
CGContextAddPath(context, pathRef);
CGContextStrokePath(context);
CGPathRelease(pathRef);
I don't know why the original method I used above does not work however. I will figure that out next.

Touch events on MKMapView's overlays

In the app I'm currently designing I have a MKMapView with overlays on it (customized MKPolylines btw) and I would like to be able to detect touch events on these overlays and assign a specific action to each overlay. Could any one help me on this one ?
Thanks !
Benja
This can be solved combining How to intercept touches events on a MKMapView or UIWebView objects? and How to determine if an annotation is inside of MKPolygonView (iOS). Add this in viewWillAppear:
WildcardGestureRecognizer * tapInterceptor = [[WildcardGestureRecognizer alloc] init];
tapInterceptor.touchesBeganCallback = ^(NSSet * touches, UIEvent * event) {
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self.mapView];
CLLocationCoordinate2D coord = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
MKMapPoint mapPoint = MKMapPointForCoordinate(coord);
for (id overlay in self.mapView.overlays)
{
if ([overlay isKindOfClass:[MKPolygon class]])
{
MKPolygon *poly = (MKPolygon*) overlay;
id view = [self.mapView viewForOverlay:poly];
if ([view isKindOfClass:[MKPolygonView class]])
{
MKPolygonView *polyView = (MKPolygonView*) view;
CGPoint polygonViewPoint = [polyView pointForMapPoint:mapPoint];
BOOL mapCoordinateIsInPolygon = CGPathContainsPoint(polyView.path, NULL, polygonViewPoint, NO);
if (mapCoordinateIsInPolygon) {
debug(#"hit!")
} else {
debug(#"miss!");
}
}
}
}
};
[self.mapView addGestureRecognizer:tapInterceptor];
WildcardGestureRecognizer is in the first linked answer. Calling mapView:viewForOverlay: won't be cheap, adding a local cache of those would help.
Just in case it might help some of you...
I couldn't find a way to do that but I added an annotation on my overlays (Anyway, i needed to do that to display some information) and then I could get the touch event on this annotation. I know it is not the best way to do it but in my situation, and maybe yours, it works ;) !

Blackberry - how to resize image?

I wanted to know if we can resize an image. Suppose if we want to draw an image of 200x200 actual size with a size of 100 x 100 size on our blackberry screen.
Thanks
You can do this pretty simply using the EncodedImage.scaleImage32() method. You'll need to provide it with the factors by which you want to scale the width and height (as a Fixed32).
Here's some sample code which determines the scale factor for the width and height by dividing the original image size by the desired size, using RIM's Fixed32 class.
public static EncodedImage resizeImage(EncodedImage image, int newWidth, int newHeight) {
int scaleFactorX = Fixed32.div(Fixed32.toFP(image.getWidth()), Fixed32.toFP(newWidth));
int scaleFactorY = Fixed32.div(Fixed32.toFP(image.getHeight()), Fixed32.toFP(newHeight));
return image.scaleImage32(scaleFactorX, scaleFactorY);
}
If you're lucky enough to be developer for OS 5.0, Marc posted a link to the new APIs that are a lot clearer and more versatile than the one I described above. For example:
public static Bitmap resizeImage(Bitmap originalImage, int newWidth, int newHeight) {
Bitmap newImage = new Bitmap(newWidth, newHeight);
originalImage.scaleInto(newImage, Bitmap.FILTER_BILINEAR, Bitmap.SCALE_TO_FILL);
return newImage;
}
(Naturally you can substitute the filter/scaling options based on your needs.)
Just an alternative:
BlackBerry - draw image on the screen
BlackBerry - image 3D transform
I'm not a Blackberry programmer, but I believe some of these links will help you out:
Image Resizing Article
Resizing a Bitmap on the Blackberry
Blackberry Image Scaling Question
Keep in mind that the default image scaling done by BlackBerry is quite primitive and generally doesn't look very good. If you are building for 5.0 there is a new API to do much better image scaling using filters such as bilinear or Lanczos.
For BlackBerry JDE 5.0 or later, you can use the scaleInto API.
in this there is two bitmap.temp is holding the old bitmap.In this method you just pass
bitmap ,width,height.it return new bitmap of your choice.
Bitmap ImgResizer(Bitmap bitmap , int width , int height){
Bitmap temp=new Bitmap(width,height);
Bitmap resized_Bitmap = bitmap;
temp.createAlpha(Bitmap.HOURGLASS);
resized_Bitmap.scaleInto(temp , Bitmap.FILTER_LANCZOS);
return temp;
}
Here is the function or you can say method to resize image, use it as you want :
int olddWidth;
int olddHeight;
int dispplayWidth;
int dispplayHeight;
EncodedImage ei2 = EncodedImage.getEncodedImageResource("add2.png");
olddWidth = ei2.getWidth();
olddHeight = ei2.getHeight();
dispplayWidth = 40;\\here pass the width u want in pixels
dispplayHeight = 80;\\here pass the height u want in pixels again
int numeerator = net.rim.device.api.math.Fixed32.toFP(olddWidth);
int denoominator = net.rim.device.api.math.Fixed32.toFP(dispplayWidth);
int widtthScale = net.rim.device.api.math.Fixed32.div(numeerator, denoominator);
numeerator = net.rim.device.api.math.Fixed32.toFP(olddHeight);
denoominator = net.rim.device.api.math.Fixed32.toFP(dispplayHeight);
int heighhtScale = net.rim.device.api.math.Fixed32.div(numeerator, denoominator);
EncodedImage newEi2 = ei2.scaleImage32(widtthScale, heighhtScale);
Bitmap _add =newEi2.getBitmap();
I am posting this answers for newbie in Blackberry Application development. Below code is for processing Bitmap images from URL and Resizing them without loass of Aspect Ratio :
public static Bitmap imageFromServer(String url)
{
Bitmap bitmp = null;
try{
HttpConnection fcon = (HttpConnection)Connector.open(url);
int rc = fcon.getResponseCode();
if(rc!=HttpConnection.HTTP_OK)
{
throw new IOException("Http Response Code : " + rc);
}
InputStream httpInput = fcon.openDataInputStream();
InputStream inp = httpInput;
byte[] b = IOUtilities.streamToBytes(inp);
EncodedImage img = EncodedImage.createEncodedImage(b, 0, b.length);
bitmp = resizeImage(img.getBitmap(), 100, 100);
}
catch(Exception e)
{
Dialog.alert("Exception : " + e.getMessage());
}
return bitmp;
}
public static Bitmap resizeImage(Bitmap originalImg, int newWidth, int newHeight)
{
Bitmap scaledImage = new Bitmap(newWidth, newHeight);
originalImg.scaleInto(scaledImage, Bitmap.FILTER_BILINEAR, Bitmap.SCALE_TO_FIT);
return scaledImage;
}
The Method resizeImage is called inside the method imageFromServer(String url).
1) the image from server is processed using EncodedImage img.
2) Bitmap bitmp = resizeImage(img.getBitmap(), 100, 100);
parameters are passed to resizeImage() and the return value from resizeImage() is set to Bitmap bitmp.

Resources