I want to create a CGPath to look like a trail in an overview perspective. I have the following code in a UIView subclass. I know I am entering the methods through NSLogs. The CGPath doesn't appear on the screen.
- (void)drawRect:(CGRect)rect{
CGMutablePathRef p = CGPathCreateMutable();
CGPathMoveToPoint( p, NULL , 150 , 150 );
CGPathMoveToPoint( p, NULL , 300 , 300 );
CGPathMoveToPoint( p, NULL , 100 , 150 ) ;
CGPathMoveToPoint( p, NULL , 150 , 150 );
CGPathAddLineToPoint( p, NULL , 300 , 300 );
CGPathAddLineToPoint( p, NULL , 100 , 150 ) ;
CGPathAddLineToPoint( p, NULL , 150 , 150 );
CGPathCloseSubpath( p ) ;
CGContextRef context=UIGraphicsGetCurrentContext();
CGContextBeginPath(context);
CGContextAddPath ( context, p ) ;
CGContextSaveGState(context);
CGColorRef redColor = [UIColor colorWithRed:1.0 green:12.0 blue:0.0 alpha:0.0].CGColor;
CGContextSetFillColorWithColor(context, redColor);
CGContextSetLineWidth(context, 20.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextStrokePath(context);
CGContextFillPath ( context ) ;
CGContextDrawPath(context, kCGPathFill);
CGContextRestoreGState(context);
}
Nothing shows up
In advance thanks
The frameworks ensure that in -drawRect: there is already an appropriate graphics context set up for you and pointed at the display device. You only need UIGraphicsBeginImageContext()/UIGraphicsEndImageContext() if you are setting up to render someplace else, such as to an image.
Delete those calls and things will behave a lot better. Right now you are rendering to an off-screen buffer, not to the view itself.
Edit: You should, however, add a pair of CGContextSaveGState() / CGContextRestoreGState() calls around your code, however. This will ensure you don't contaminate the graphics context for other graphics code if your -drawRect: is used in certain ways.
Edit 2: Alright, I see that you have resolved the issue after your last response, but for the benefit of archives, I am going to point out that you never call -drawRect: directly (except in some obscure cases that don't apply here). Since you had called it directly, no graphics context had been set up, hence the crash. The proper way to trigger redraw is to send the view -setNeedsDisplay; this will cause the frameworks to setup a graphics context and invoke -drawRect: for you at the appropriate time in the run loop.
If on iOS, switch to bezier paths using UIBezierPath. Sure-fire to work.
Also, I've noticed, each of your moveToPoints are in a single row, when they should have one addLineToPoint right after them, like so:
CGPathMoveToPoint(p, NULL, 150, 150);
CGPathAddLineToPoint( p, NULL, 300, 300);
CGPathMoveToPoint(p, NULL, 300, 300 ;
CGPathAddLineToPoint(p, NULL, 100, 150);
CGPathMoveToPoint(p, NULL, 100, 150);
CGPathAddLineToPoint(p, NULL, 100, 150);
CGPathMoveToPoint(p, NULL, 150, 150);
CGPathAddLineToPoint(p, NULL, 150, 150);
But you'll want to switch to UIBezierPaths anyway once you see how easy they are.
Related
I'm trying to resize a gif in a smaller version.
this is what i come up with at the moment:
from PIL import Image
def process_gif(in_path, out_path= 'out.gif', size= (32,32)):
with Image.open(in_path) as im :
images = []
durations = []
for i in range(im.n_frames - 1, -1, -1):
im.seek(i)
im.thumbnail(size, Image.Resampling.LANCZOS) # noqa
im_temp = im.copy()
images.insert(0, im_temp)
durations.append(im.info['duration'])
images[0].save(
out_path,
format='gif',
interlace=True,
save_all=True,
append_images=images[1 :],
loop=0,
duration=durations,
disposal=2,
background=(255,255,255,255),
optimize=False
)
when i try to create the gif the first frame have the correct background and the rest have isssue.
with this gif as imput in.gif
i get those frame in the images before saving: 0 1 2 3
and this is the output out.gif
spent some time figuring out where is the error with no clue, the output should have trasparent background in every frame of the GIF
P.S. i noticed imgur colored the trasparent frame, the in.gif, 0, 1, 2, 3 all have trasparent background, open with your image viewer should let you see better
After some other attemp i looked for trasparency doing print(im_temp.info) before inserting the resized image, NOTE that the cycle it's backward to solve another issue so it's last frame to first frame
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70}
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70}
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70}
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70, 'transparency': 48, 'extension': (b'NETSCAPE2.0', 219)}
from PIL import GifImagePlugin
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_DIFFERENT_PALETTE_ONLY
using this solved my problem
I want to display the horizontal and vertical ruler on the frame with gtk3.
this is my frame:
I want to display ruler on the frame like this:
BUT GtkRuler has been removed from GTK 3 for being unmaintained and too specialized!!
this is my GTK3/c cpde:
/* The horizontal ruler goes on top. As the mouse moves across the
* drawing area, a motion_notify_event is passed to the
* appropriate event handler for the ruler. */
hrule = gtk_hruler_new ();
gtk_ruler_set_metric (GTK_RULER (hrule), GTK_PIXELS);
gtk_ruler_set_range (GTK_RULER (hrule), 7, 13, 0, 20);
g_signal_connect_swapped (area, "motion_notify_event",
G_CALLBACK (EVENT_METHOD (hrule, motion_notify_event)),
hrule);
gtk_table_attach (GTK_TABLE (table), hrule, 1, 2, 0, 1,
GTK_EXPAND|GTK_SHRINK|GTK_FILL, GTK_FILL, 0, 0);
/* The vertical ruler goes on the left. As the mouse moves across
* the drawing area, a motion_notify_event is passed to the
* appropriate event handler for the ruler. */
vrule = gtk_vruler_new ();
gtk_ruler_set_metric (GTK_RULER (vrule), GTK_PIXELS);
gtk_ruler_set_range (GTK_RULER (vrule), 0, YSIZE, 10, YSIZE );
g_signal_connect_swapped (area, "motion_notify_event",
G_CALLBACK (EVENT_METHOD (vrule, motion_notify_event)),
vrule);
gtk_table_attach (GTK_TABLE (table), vrule, 0, 1, 1, 2,
GTK_FILL, GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0);
What ideas on how to solve this task would you suggest? Or on what resource on the internet can I find help?
If your code has a compatible license, you can simply copy the GtkRuler out of GTK 2 into your code, making any changes necessary to make it work with GTK 3.
I'm trying to use Julia with GTK and Cairo to draw onto a canvas. I think the following code (adapted from the example fragments on the GTK.jl page) should work, but it does not. (Other GTK widgets work, but not the canvas)
I would appreciate if someone can suggest what is wrong with this code, or give a pointer to a complete example.
using Gtk.ShortNames
using Cairo
function drawfn(w)
ctx = Gtk.getgc(w)
Cairo.set_coords(ctx, 0, 0, 800, 600, 0, 800, 0, 600)
h = Gtk.height(w)
w = Gtk.width(w)
Gtk.rectangle(ctx, 0, 0, w/2, h/2)
Gtk.set_source_rgb(ctx, 0, 0, 1)
Gtk.fill(ctx)
end
function main()
win = Gtk.#Window("stuff", 800,600)
c = Gtk.#Canvas()
Gtk.push!(win,c)
Gtk.draw(drawfn, c)
Gtk.showall(win)
end
main()
I think this was a bug in version 0.8.1 of Gtk.jl. I posted an issue to github after which vtjnash fixed it immediately and tagged version 0.8.2.
I'm writing a Framer.js function to simulate the 'splash' effect when you tap a button or a layer, as per Google Material Design.
It looks something like this
tapSplash = (tapX,tapY) ->
tapSplashLayer = new layer
backgroundColor: "#ffffff"
opacity: 0.2
width: 500, height: 1500
borderRadius: 1500
midX: tapX
midY: tapY
After this, I have some code to run the animation.
My question is, how do I get the tapX and tapY coordinates? It is not good enough to use the midpoint of the layer that has been clicked/tapped - I want the animation to originate from the exact point the user tapped on
Check out your own answer to the question.
I've since then forked it and made changes so that taps on a computer or taps on a mobile device are recognized separately.
https://github.com/carignanboy1/Material-Design-Interactions/tree/improved-touch
touchEvent = Events.touchEvent(event)
if Utils.isPhone() || Utils.isTablet()
tX = touchEvent.clientX - layer.x
tY = touchEvent.clientY - layer.y
else
tX = touchEvent.offsetX
tY = touchEvent.offsetY
It seems like a trivial problem, but nothing I've tried will make the background transparent.
use strict;
use warnings;
use GD
GD::Image->trueColor(1);
my $im = new GD::Image(100, 100);
my $clear = $im->colorAllocateAlpha(255, 255, 255, 127);
my $black = $im->colorAllocateAlpha(0, 0, 0, 0);
$im->alphaBlending(0);
$im->filledRectangle(0, 0, 100, 100, $clear);
$im->alphaBlending(1);
$im->stringFT($black, "a-ttf-font.ttf", 12, 0, 20, 20, "x");
binmode STDOUT;
print $im->png;
Thanks for any guidance.
Are you using $im->saveAlpha(1)? Otherwise the alpha information is only useful in constructing the image. The saved image won't be transparent.
A quick and dirty method, which might not be good enough for your purposes, is to forget about the alpha channel and use the GD::Image::transparent method.