I have an ximage which I want to zoom in on, and display. I'm currently taking the naive approach:
allocate bigger image
use nearest-neighbor interpolation to fill it in.
put the whole image on a pixmap.
Which works, but slowly, and crawls once I approach bigger zoom levels, like 800%. The gimp, however, can zoom in to 3200% and still feel snappy. What's the approach taken here? Should I only fill one screen at a time? But then what about scrolling: wouldn't performing interpolation, and an XPutImage, and an XCopyArea on each expose kill performance?
I'm not expert in Xlib, but in my opinion a good approach would be to draw only the zoomed part, instead of computing the interpolation of the entire image.
For scrolling, if you are looking for performances, you may copy the part of the old zoom which is still visible in the new position, and compute the interpolation of the "discovered" pixels. For example, when scrolling down, you may copy the bottom of the previous image and paste it higher, and then compute/draw the new visible stuff at the bottom.
Most modern X11 applications don't use Xlib directly much, if at all. My guess would be that Gimp is rendering the zoomed image into a buffer itself and drawing that to the window, rather than working with the image in an XImage.
Related
What is the correct way to zoom in and out of a scene in SceneKit?
So when I enable the standard camera control in a scene and pinch in and out the scene gets bigger and smaller. What is that pinch really doing?
Is it changing the scale of the whole scene? Is it moving the camera closer?
I want to implement the same effect but programmatically.
What should I do to obtain the same effect?
When you pinch it's the field of view (xFox and yFov properties) of your camera that's changed. Changing the field of view is not the best way to zoom because it can dramatically change the perspective.
Moving the camera closer to your object is a good solution.
Also note that the "free camera" behavior is suitable for 3D viewers (such as Preview.app) but will rapidly become frustrating in any other app. At this point you might want to implement your own camera controller.
At any given point the camera has a position in space, it has a rotation for each of its own axis compared to each of the world axis, to have a zoom in and zoom out, you have to move the camera in the +z/-z axis direction.
Along the Cameras own Z/-Z axis.
For those on OSX, I used this in my SCNView subclass:
override func scrollWheel(theEvent: NSEvent) {
let cam = pointOfView!.camera
cam!.xFov = cam!.xFov - Double(theEvent.deltaY)
cam!.yFov = cam!.yFov - Double(theEvent.deltaY)
}
There are two (minor) problems that could be addressed with a little extra code. One is that the values can go negative, at which point the image is flipped inside-out. The other is that mouse acceleration can cause the zoom level to go too fast if you really spin the wheel. Limits on both of these would be a good idea, but in my app the behaviour was fine as it is above.
I need to display many markers on a WPF image. The markers can be lines, circles, squares, etc. and there can be several hundreds of them.
Both the image source and the markers data are updated every few seconds. The markers are associated with specific pixels on the image and their size should be absolute in relation to the screen (i.e. when I move the image the markers should move along with it, but if i zoom in, they should take the same space of the screen as before).
Currently, I've implemented this using the AdornerLayer. This solution has several problems but the most significant one is that the UI doesn't fare well under the load even for 120 such markers.
I wanted to ask what would be the best way to go about implementing this? I thought of two solutions:
Inherit from Canvas and make sure it is invalidated not for every
added marker but for a range of markers at once
Create a control that holds an image and change its OnDraw to draw all the markers
I would appreciate some pointers from someone with experience with a similar problem.
Your use case looks quite specialized, so a specialized solution seems in order. I'd try a variant of your second option — extend Image, overriding its OnRender method.
My aim is to have 3 images shrink, grow, and move along a horizontal axis depending on selection. Using Auto Layout seems to make the images jump about as they try to fulfil the Top space to superview / Bottom space to superview constraints.
So to combat this I have put all the images inside their own UIView. The UIView is set to the maximum size the images can grow to, it is centred on the horizontal axis. So now all the images must do is stay centred inside their corresponding UIView. This has fixed my problem as the UIViews perform the horizontal translation, while the images shrink/grow inside while remaining centred. My question is - is this the correct way to do this? It seems very long and like I am perhaps misusing the ability of Auto Layout. I have to perform similar tasks with more images and so any advice is welcome! Thanks.
I've just written a little essay on this topic here:
How do I adjust the anchor point of a CALayer, when Auto Layout is being used?
Basically autolayout does not play at all well with any kind of view transform. The easiest solution is to take your view out of autolayout's control altogether, but alternatively you can give it only constraints that won't fight back against the particular kind of transform you intend to apply. That second solution sounds like just the sort of thing you're doing.
Lets say I have a Canvas with one Image centered on the screen. When I move the image away from the center, lets say to the upper right corner, I want it to be skewed as if the Canvas was a perspective 3d-camera with a certain FOV. Can this be done somehow? Im playing around with the Perspective-property in Silverlight for WP7 but I cant get the effect Im after.
I believe this may be what you're looking for: How to Set this Kind of Perspective Transform in Matrix3D?
We have a Silverlight application that shows text over video. Both the text and video can be considered variables. Sometimes we might have a dark video, sometimes a bright video, sometimes a video that has sections of both.
Think of credits at the end of a movie. We want to ensure the end user can always read the text being show over the video. The text is always an overlay on top of the video.
The simple solution is to two show the text twice once in white and once in black with a small offset. This almost works but actually looks a little rough, and takes away from the user experience.
Ideally we would have the text with slight semitransparent glow around the edges. So if the text were white there would be a black glow right around the edges.
Is there a way to do this? Or is there an equal or better work-around?
I've done this with the DropShadow pixel shader effect in Silverlight 3. It works nicely, but since the pixel shaders aren't executed on the hardware, it can have a pretty heavy impact on the performance of the application.
If you wanted to get ambitious, you could write your own pixel shader. Silverlight 3 supports HLSL Shaders.
You could try displaying it with a contrasting outline, rather than just a "drop shadow" like you get if you display it once with a small offset. To do this, display it four times in one color, then a fifth time with a contrasting color, centered over the four previous copies. The four first ones should be offset one pixel up, right, down and left of the center.
The net effect should be an outline. Of course, perhaps this too looks "rough", since it's computer-generated and thus not perfect with respect to issues like kerning, spacing between characters, and so on. But it's quick to try, at least.
In general, automatically finding good contrasting colors when the background is video sounds a bit difficult. In the worst case, the video contains text just like the one you want to display. The correct solution in that case is hard to imagine.
Sounds similar to the problem of ensuring subtitles are always readable in films/TV. The most robust, but not necessarily most elegant solution, is to have a coloured background rectangle for the text which is either opaque or has a low transparency value - often grey or black with good contrasting foreground colour.