I want to set different opacity for different pixels in UIView.
So, I need to find implementations for method [self setProperOpacity:myView forX:x forY:y]; in code (so that function should set alfa value for proper pixels):
for (int x = 0; x < 320; x++)
{
for (int y = 0; y < 460; y++)
{
[self setProperOpacity:myView forX:x forY:y];
}
}
I will grateful for any approach of implementation [self setProperOpacity:myView forX:x forY:y];
I'm guessing your view is initially filled with black, and you want to clear some of the pixels to transparent. To do that you need to use the core graphics methods. Depending on where you want the code and how you want to do it the below code could be used either in drawRect of the view or to create a masking image (you need to get the context as appropriate):
CGContextRef ctx = ...;
CGContextSetFillColorWithColor(ctx, [UIColor blackColor].CGColor);
CGContextSetBlendMode(ctx, kCGBlendModeNormal);
CGContextFillRect(ctx, CGRectMake(0, 0, 320, 460));
// CGContextSetBlendMode(ctx, kCGBlendModeClear); // if you want to clear
CGContextSetFillColorWithColor(ctx, [[UIColor blackColor] colorWithAlphaComponent:0].CGColor);
for (int x = 0; x < 320; x++)
{
for (int y = 0; y < 460; y++)
{
CGContextFillRect(ctx, CGRectMake(x, y, 1, 1));
}
}
The answer is based around the idea that you have a partially transparent view over the top of some other image (in another view behind) that you're trying to mask out. If you just have the image and you don't want multiple views then you could (in drawRect) draw the image to the context and then loop over the pixels that should not be transparent and paint them in another color using the code above.
Related
I have a UIImageView in my Nib file that stretches the width of the screen. What I'd like to do is have the middle third of the image remain the same height and width when autoresizing is done (with device rotation) and have only the 1st and 3rd thirds of the image stretched.
Any ideas how to do this?
There is no straight-forward way to do this as far as I know. Here is one way to do it:
Instead of one ImageView, create 3 UIImageView with equal width and height(1/3rd of original image). Upper and lower ImageView will stick to the top and bottom edge respectively, middle ImageView will have flexible bottom and top margin. You need to set the contentMode property of middle ImageView to UIViewContentModeScaleAspectFit(or UIViewContentModeCenter based on how you want to handle rotation) and the other ones to UIViewContentModeScaleToFill. You can set all these property from IB.
Now you need to to set the image source of each one from code. In the viewDidLoad method slice the UIImage into 3 parts using the solutions from this post or using the following code snippet:
-(NSMutableArray *)getImagesFromImage:(UIImage *)image withRow:(NSInteger)rows withColumn:(NSInteger)columns
{
NSMutableArray *images = [NSMutableArray array];
CGSize imageSize = image.size;
CGFloat xPos = 0.0, yPos = 0.0;
CGFloat width = imageSize.width/rows;
CGFloat height = imageSize.height/columns;
for (int y = 0; y < columns; y++) {
xPos = 0.0;
for (int x = 0; x < rows; x++) {
CGRect rect = CGRectMake(xPos, yPos, width, height);
CGImageRef cImage = CGImageCreateWithImageInRect([image CGImage], rect);
UIImage *dImage = [[UIImage alloc] initWithCGImage:cImage];
[images addObject:dImage];
xPos += width;
}
yPos += height;
}
return images;
}
You may need to tweak a few things, but hopefully you get the idea.
If you have the option, you can pre-split the image into 3 parts using photoshop/gimp and place them into the bundle. In that case you don't need to do image splitting in the code and everything can be done from IB.
Hope this helps :)
I wanted to draw a vertical single bar graph. I was trying to do it using DrawRect, but could not able to do so. Can nay one hlep me to knwo if this can be done easily by providing start and end point in view to change the color.
thanks
If you have a custom view, it's just a matter of drawing the lines and rectangles that you want. For example:
- (void)drawRect:(CGRect)rect
{
CGAffineTransform t = CGAffineTransformMakeScale(1, -1);
self.transform = t;
CGFloat baseline = 50;
CGFloat inset = 40;
CGFloat barWidth = 20;
CGFloat barHeight = 80;
CGRect r = CGRectMake(inset + barWidth, baseline, barWidth, barHeight);
UIBezierPath *p = [UIBezierPath bezierPathWithRect:r];
[[UIColor redColor] set];
[p fill];
p = [UIBezierPath bezierPath];
[p moveToPoint:CGPointMake(inset, baseline)];
[p addLineToPoint:CGPointMake(inset + 3 * barWidth, baseline)];
[[UIColor blackColor] set];
[p stroke];
}
produces this:
I've created a UIView subclass with the -drawRect: method above and created an instance of that view that's the size of the window. Note that I flipped the coordinate system using a transform -- you don't have to do that, but drawing with the origin at the lower left corner can be easier.
try this one
1. http://www.raywenderlich.com/13271/how-to-draw-graphs-with-core-plot-part-2
2 OVGraph.- a library for the graphs
I have UIView class and in method I want to draw first rectangles and sometimes circle
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
if ([WhatToDraw isEqual:#"Fields"]) {
[self DrawField:context];
}
if ([WhatToDraw isEqual:#"Ball"]) {
[self DrawBall:context x:20 y:20];
}
}
-(void)DrawBall:(CGContextRef)context x:(float) x y:(float) y
{
UIGraphicsPushContext(context);
CGRect rect = CGRectMake(x, y, 25, 25);
CGContextClearRect(context, rect);
CGContextFillEllipseInRect(context, rect);
}
-(void)DrawField:(CGContextRef)context
{
columns = 6;
float offset = 5;
float boardWidth = self.frame.size.width;
float allOffset = (columns + 2) * offset;
float currentX = 10;
float currentWidth = (boardWidth - allOffset) / columns;
float currentHeight = currentWidth;
self.fieldsArray = [[NSMutableArray alloc] init];
//create a new dynamic button board
for (int columnIndex = 0; columnIndex<columns; columnIndex++) {
float currentY = offset;
for (int rowIndex=0; rowIndex<columns; rowIndex++) {
UIGraphicsPushContext(context);
//create new field
CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 1.0);
CGContextBeginPath(context);
CGRect rect = CGRectMake(currentX, currentY, currentWidth, currentHeight);
CGContextAddRect(context, rect);
CGContextFillPath(context);
currentY = currentY + offset + currentHeight;
}
currentX = currentX + offset + currentWidth;
}
}
I also have method changing what to draw
-(void)Draw:(NSString*)Thing
{
self.WhatToDraw = Thing;
[self setNeedsDisplay];
}
Drawing rectangles (Fields) is ok, but when I click button to draw circle all rectangles disappear and only circle was drawn.
How can I draw circle on existing rectangle ?
The Problem
Your problem is that when a UIView redraws a region as marked by setNeedsDisplay or setNeedsDisplayInRect it will completely clear that region before executing your drawing code. This means that unless you draw both the rectangles and circle in a single drawing operation within drawRect you will never see the two both drawn in the area you choose to redraw, whether it be the entire view bounds with setNeedsDisplay or a specific area with setNeedsDisplayInRect.
The Solutions
There's no reason why you can't draw both the rectangles and circle each time within drawRect and optimise the performance of the drawing by only redrawing the regions necessary with setNeedsDisplayInRect.
Alternatively you could break up the content using CALayers and have the rectangles in one layer and the circle in another. This would allow you to leverage the animation capabilities of Core Animation. Core animation provides a simple and effective way to manipulate onscreen layers with implicit animations such as moving, resizing, changing colour etc.
my guess, the CGContextClearRect call in your DrawBall method is the responsable of rectangles disappearing... From Apple documentation: If the provided context is a window or bitmap context, Quartz effectively clears the rectangle.
Is it possible to draw a UIImage on top of the CATiledLayer. The main idea is to note the position on the view. I have used PhotoScroller example from Apple Library and I am trying to add an UIImage on top of the tileRect. Any help will be appreciated.
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
/**** Trying to add UIImage on top of CGRect rect. But not working.****/
CGRect pointRect = CGRectMake(100,100,32,32);
UIImage *image = [UIImage imageNamed:#"map-pointer32.png"];
[image drawInRect:pointRect];
// get the scale from the context by getting the current transform matrix, then asking for
// its "a" component, which is one of the two scale components. We could also ask for "d".
// This assumes (safely) that the view is being scaled equally in both dimensions.
CGFloat initialScale = CGContextGetCTM(context).a;
NSString *value = [NSString stringWithFormat:#"%.3f", initialScale];
CGFloat scale = [value floatValue];
CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
CGSize tileSize = tiledLayer.tileSize;
// Even at scales lower than 100%, we are drawing into a rect in the coordinate system of the full
// image. One tile at 50% covers the width (in original image coordinates) of two tiles at 100%.
// So at 50% we need to stretch our tiles to double the width and height; at 25% we need to stretch
// them to quadruple the width and height; and so on.
// (Note that this means that we are drawing very blurry images as the scale gets low. At 12.5%,
// our lowest scale, we are stretching about 6 small tiles to fill the entire original image area.
// But this is okay, because the big blurry image we're drawing here will be scaled way down before
// it is displayed.)
tileSize.width /= scale;
tileSize.height /= scale;
// calculate the rows and columns of tiles that intersect the rect we have been asked to draw
int firstCol = floorf(CGRectGetMinX(rect) / tileSize.width);
int lastCol = floorf((CGRectGetMaxX(rect)-1) / tileSize.width);
int firstRow = floorf(CGRectGetMinY(rect) / tileSize.height);
int lastRow = floorf((CGRectGetMaxY(rect)-1) / tileSize.height);
for (int row = firstRow; row <= lastRow; row++) {
for (int col = firstCol; col <= lastCol; col++) {
UIImage *tile = [self tileForScale:scale row:row col:col];
CGRect tileRect = CGRectMake(tileSize.width * col, tileSize.height * row,
tileSize.width, tileSize.height);
// if the tile would stick outside of our bounds, we need to truncate it so as to avoid
// stretching out the partial tiles at the right and bottom edges
tileRect = CGRectIntersection(self.bounds, tileRect);
[tile drawInRect:tileRect];
if (self.annotates) {
// [[UIColor whiteColor] set];
CGContextSetLineWidth(context, 6.0 / scale);
CGContextStrokeRect(context, tileRect);
}
}
}
}
Probably the best solution would be to add the image in separate view, without any catiledlayer.
You can add an empty view, and add the view with the the catiledlayer an the uiimageview to that view.
how to use setpixel function in iphone
If you're drawing a UIView, I don't believe there is any way to set an individual pixel. Instead, try using CoreGraphics by overriding your UIView's drawRect: method:
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect pixelRect;
pixelRect.x = 100; // or whatever position needs a pixel drawn
pixelRect.y = 100;
pixelRect.width = 1;
pixelRect.height = 1;
CGContextSetRGBFillColor(ctx,1,1,1,1.0); // just fill with a white color
CGContextFillRect(ctx, pixelRect);
Another approach may be to consider using OpenGL and just drawing points that way:
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (0, rect.size.width, rect.size.height, 0, 0, 1); // set to the drawing rectangle's size
glDisable(GL_DEPTH_TEST);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.375, 0.375, 0);
glClear(GL_COLOR_BUFFER_BIT);
// draw the actual point
glBegin(GL_POINTS);
glColor3f(1.0f, 1.0f, 1.0f); // white color
glVertex2f(x, y);
glEnd();