I am having different Texture Brushes I am having the image of those texture of each pixel of the stroke I want to assign the texture to the CGPath and change the width .
I need to assign the texture image and change the width to the slider response.
You achieve this in the following order:
Use CGLayerCreateWithContext to create a CGLayer, during this stage, the slider value is obtained and used as the CGSize in the initializer.
Use CGLayerGetContext to get the context of the CGLayer created, then you render your brush texture with the context, for example, CGContextDrawImage.
Use the completed CGLayer as a texture and draw it on screen with CGContextDrawLayerAtPoint, since you got your CGPath, you need to manually calculate the density of your drawing, and generate an array of CGPoint to be used as a parameter in the drawing function.
You may reference the Quartz 2D Programming Guide by Apple.
Related
I am working on API which requires me set up a outer geometry mask on ID2D1Rendertarget such that any draw call after that only draws portion of drawings which lies outside this geometry.
https://msdn.microsoft.com/en-us/library/windows/desktop/dd756675(v=vs.85).aspx explains how can we setup a inner geometry mask on ID2D1Rendertarget such that any draw call after that only draws portion of drawings which lies inside this geometry.I want to implement just opposite of that. Is this possible? Any help is deeply appreciated.
One way to do this is to subtract your geometry from a rectangle that fills the entire render target. Check out the MSDN page on combining geometries. I have a small code example below:
ComPtr<ID2D1PathGeometry> invertedGeometry;
ComPtr<ID2D1RectangleGeometry> rectangleGeometry;
d2dFactory->CreateRectangleGeometry(
{ 0, 0, targetWidth, targetHeight },
&rectangleGeometry
);
ComPtr<ID2D1GeometrySink> geometrySink;
d2dFactory->CreatePathGeometry(&invertedGeometry);
invertedGeometry->Open(&geometrySink);
rectangleGeometry->CombineWithGeometry(
pathGeometry.Get(),
D2D1_COMBINE_MODE_EXCLUDE,
D2D1::Matrix3x2F::Identity(),
geometrySink.Get()
);
geometrySink->Close();
Use the inverted geometry as the geometric mask instead of the original path geometry.
A second way to do this is to rasterize your geometry to a bitmap and use it as an opacity mask. You can flip the colors depending on whether or not you want the inside or outside to mask.
I have a viewport with some shapes that I draw by using Direct2D. At the moment when I change somehting, for example I set a Rectangle fill from red to green, I first clear the render target and then I draw again all the shapes with the new properties.
Since I know the position and the area of the rectangle I modified, is there a way to clear and re-draw only the area that has been updated insted of re-draw all the thousand shapes I have?
The documentation for:
IDXGISwapChain1::Present1(
UINT SyncInterval,
UINT PresentFlags,
[in] const DXGI_PRESENT_PARAMETERS *pPresentParameters);
states that
An app can use Present1 to optimize presentation by specifying scroll and dirty rectangles.
This information about the modified rectangles is supplied via the *pPresentParameters parameter. For details see:
DXGI_PRESENT_PARAMETERS structure
I have an image stored in a RGBA buffer. Now I want to draw this data in the UIView's drawRect method:
- (void)drawRect:(CGRect)rect
{
// draw RGBA here
}
One means would be to copy the data into an UIImage (outside the drawRect method) and draw this UIImage. Is there a method to directly draw the data without having to make another copy in an UIImage?
Regards,
Using the drawrect function of a UIView for this purpose would be horrendously slow. Any time you animate the view, move it, move something else on top of it or whatever it would have to be redrawn (slow process). UIImageView is optimized for this task and it would be beneficial to use it.
But if you are dead set on drawrect then you would have to create "pixel" rectangles by taking the width and height of your UIView divided by the width and height of your image (in pixels). Then iterate through every pixel row and column and use the CGContextSetFillColor and CGContextFillRect. It would probably make performance sense to sort the array of colors into like colors and draw the same color all at once. But still much slower than UIImageView. The memory overlap of having your array and a UIImageView is not bad enough to outweigh the beneifits.
I have this app using which one can draw basic shapes like rectangle, eclipse, circle, text etc.
I also allow free form drawing, which is stored as set-of-points, on the canvas.
Also a user can resize and move around these objects by operating on the selection handles that appear when an object is selected.
In addition the user should be able to zoom and pan the canvas.
I need some inputs on how to efficiently implement this drawing functionality.
I have following things in mind -
Use UIView's InvalidateRect and drawRect
Have a UIView for the main canvas and for each inserted object - invalidate the correspoding rect and redraw all the objects which intersects that rect in the drawRect function of the UIView.
Have a UIView and use CALayer ?
every one keep mentioning about the CALayer , I dont have much idea on this, before I venture into this I wanted a quick input on whether this route is worth taking.
like, https://developer.apple.com/library/ios/#qa/qa1708/_index.html
Have a UIImageView as canvas and when drawing each object, we do this
i) Draw the object into offscreen CGContext, basically, create a new CGContext by using UIGraphicsBeginImageContext, draw the shape, extract the image out of this CG context and use that as source of UIImageView's image property, but here how do I invalidate only a part of the UIImageView so that only that area gets refreshed.
Could you please suggest what is the best approach?
Is there any other efficient way to get this done?
Thanks.
Using a UIImage is more efficient for rendering multiple objects. But Using a CALayer is more efficient when moving and modifying a single object because you don't have to modify the other objects. So I think the best approach is to use a UIImage for general drawing and a CALayer for the shape that is being modified. In other words:
use a CALayer to draw the shape being added or modified, but don't draw it on the UIImage
use a UIImage to draw the other shapes
But OpenGL is still the most efficient solution, but don't bother with that if you don't have too many objects to draw.
If you want to draw polygons, you'll have to use Quartz framework, and have your drawing methods based on CALayer. It doesn't really matter which view you'll put your CALayers in, UIImageView or UIView. I'll say UIView since you won't be needing UIImageView's properties or methods for drawing.
I have a based image and some sprites on top of the basd image movieclip... Some of the sprites can be drawn by the user using graphics api in actionscript 3. I can draw things on the sprites but I can't create an eraser like brush that can remove part of the unwanted drawings. I try using Alpha but no it doesn't work
I have googled about it and come up with the solution:
1) Linebitmapstyle... This solution is not the best one coz I my sprites can be moved so if I use linebitmapstyle, it does draw the pixel from the image to the sprite but if the sprite moved the drawn pixel won't change.
2) Masking may not work for me either....
What is the best way of creating the eraser
You may rather want to use a Bitmap to make such things easier to manipulate (unless you need to do scalable vector graphics of course!). To draw shapes you can still use the graphics API to create the shapes.
To do so, instantiate a "dummy" sprite (or another IBitmapDrawable implementation) to create the graphics and then "copy" them to the BitmapData the bitmapData.draw() function. This way you can for instance draw with the option BlendMode.ERASE in order remove the pixels of the shape.
Example (from the top of my mind) :
// creates a bitmap data canvas
var bitmapData:BitmapData = new BitmapData(500, 500);
// creates a bitmap display object to contain the BitmapData
addChild(new Bitmap(bitmapData));
// creates a dummy object to draw and draws a 10px circle
var brush:Sprite = new Sprite(); // note this is not even added to the stage
brush.graphics.beginFill(0xff0000);
brush.graphics.drawCircle(10, 10, 10);
// the matrix will be used to position the "brush strokes" on the canvas
var matrix:Matrix = new Matrix();
// draws a circle in the middle of the canvas
matrix.translate(250, 250);
bitmapData.draw(brush, matrix
// translates the position 5 pixels to the right to slightly erase the previously
// drawn circle creating a half moon
matrix.translate(5, 0);
bitmapData.draw(brush, matrix,null,BlendMode.ERASE);