Imagine that I'm working on a 1920x1080 image, doing some computations on those pixels, but I'm interested in showing to the user only a centered part of that rendered image (for example a 500x500).
There is a way to show in my window only a part of the Swapchain using its Present() function ?
I've solved my problem by using a second display doing off-screen rendering at a different resolution. After that rendering, it pass a texture2d to the smaller "real" display which crops it to adapt to the smaller resolution. Thanks anyway!
Related
I have a png that's size 150x100 , and I set the UI image to the same, but it makes a bunch of extra space around it (that can be interacted with). How do I fix this?
Image of Problem: https://imgur.com/a/2ILXY1t
Unity isn't adding extra space. The image itself HAS that space.
There are options to crop out the alpha space in Unity by using the sprite editor, but by my experience i prefer using a proper Image editor like Gimp. using one is the best way to handle your image assets.
To crop out the extra space you just have to reduce the canvas size.
Well, first you could check (in Unity) wether your Image has its property Preserve Aspect set to True.
You could click Set Native Size which is right below it, so the 'box' around your image will take it's size.
Edit: Nevermind the first two. I do not know why i thought they could solve it, i looked at your image again and i, too, think there are transparent pixels above and below it. So you should try this:
Then you could check whether your picture has any transparent pixels around it, using an image editor. If it has, you would need to cut them out.
I'm creating an image with some text and using TextureBrush for draw the text along a line repeatedly. It is working fine on the screen. when i want to print it, it looks very bad.. I've tried to create the image bigger (relative to the dpi differences) and set its resolution as the resolution of the Graphics object (For printing it is higher). Printing the image as it is looks good.. but as TextureBrush not so good.
I'm attaching all the prints - Tried to print it to PDF printer - same results as real printer - so no problem there.
first try before changing anything
Drawing the image using graphics.DrawImage(...) (The image contains The letter 'A' that I've drew in)
Printing TextureBrush
At this time it was clear that i have resolution problem so I've created my image bigger and in better resolution (as the printer dpi)
Drawing the image using graphics.DrawImage(...)
Looks perfect - Exact size and good quality. graphics.DrawImage(...) drew the picture with consideration of its size and resolution.
Now I've used this picture in my textureBrush. The result looks like this
It is bigger because the image itself is bigger - But why it does not consider resolution like graphics.DrawImage(...)..
Anyway i've decided to continue and scale down the image using TextureBrush.ScaleTransform(...) - The results looks like that
This is the best that i've reached so far.. I think the main problem is the TextureBrush that does not consider the resolution of the image.
I would really prefer to stick with the TextureBrush way (And not drawing image by image with clipping and repeating), cause it is very complex code, and complex drawing
Help anyone ?
I'm able to fill a rectangle with an image and i apply a mask on top of the image using this code
args.DrawingSession.FillRectangle(rect, imgRnd, mask);
i need to apply some transform to this image, i'am able to do that with no issue, but i have encounter a strange issue, the last pixel is repeated.
i have used
imgRnd.ExtendX = CanvasEdgeBehavior.Wrap;
imgRnd.ExtendY = CanvasEdgeBehavior.Wrap;
and the image is repeated continuously.
My question is : there is a way to draw one time the image disabling and ExtendX and ExtendY?
FillRectangle will always fill all the pixels within the specified rectangle. The edge behavior enum controls what value they are filled with if the image is positioned such that it does not completely cover the rectangle being drawn.
How exactly are you transforming the image? Can you change that to also transform the rectangle itself, so you won't be trying to fill pixels that aren't covered by the image?
Another option is to use image effects (Microsoft.Graphics.Canvas.Effects namespace) which give much more detailed control than FillRectangle over how multiple images are transformed, combined, etc.
I am working on an Application that loads live video images from a camera and displays an overlay on top of said image. The Overlay does not change often so it can be considered as still. However it usually contains about 1,000 to 10,000 Lines.
When the video image is updated there is a notable impact to the CPU load depending on whether the overlay is visible or not. The overlay does neither get invalidated nor changed, just the image behind it is changing.
My setup is this:
<Canvas>
<Image/>
<Canvas>
<OverlayElement 1/>
<OverlayElement 2/>
<OverlayElement 3/>
<.../>
</Canvas>
</Canvas>
The Image's Source is a WriteableBitmap. Every time a new camera image (type byte[]) is available, the main Canvas' Dispatcher is invoked to write the image data by using WriteableBitmap.WritePixels().
The inner Canvas contains all Overlay Elements, being
- a contour (PolyLine)
- a circle (Path with EllipseGeometry) and
- a set of Rays (Path with one Figure containing LineSgements).
The number n of Points in the contour equals the number of line Segments in the last mentioned Path. n is usually around 1,000 - 3,000.
Depending on the count and length of Lines shown in the overlay the CPU load for showing a live image varies (increases if length or count go up) even if the overlay does not change. At some point this affects the frame rate and makes the program unusable. Line length is mostly correlated with line intersection, so maybe the Path is struggling to calculate it's fill area despite it is not painted?
So how could I improve the performance here?
What bugs me most is that even if the overlay does not change, the render time increases with it's primitive count. I would expect to have constant render time once the overlay has been drawn in it's last set state. What could I do to achieve that aside from rendering the whole overlay to a bitmap?
I am also open minded for suggestions on how to get the byte[] onto the screen more efficiently. Just keep in mind this problem is part of a bigger Application and i cannot change all paradigms concentrating on how to get the image drawn.
What I have tried so far:
Override the OnRender() method of the inner Canvas, drawing the overlay myself. This works fine but has the performance issue that brings me here ;)
Use Shapes (PolyLine, Ellipse, Path) as the inner Canvas' children to hold the overlay elements. This works, too. It is faster to redraw the overlay when it changes but on the other hand worsens the performance issue when updating the background image.
Like 2., but use Freeze() on Geometries wherever possible. Has no or little performance impact.
Thanks for your help in advance.
The ImageList has a method named "Draw":
imageList.Draw(graphics, bounds.X, bounds.Y, bounds.Width, bounds.Height, imgIndex);
I use this method to draw an image on a graphics object of a PrintDocument. When using the original image size (16 x 16 pixels), the image is drawn correct. If however, I change the bounds size, nothing is drawn. Even changing the size to 32 x 32 (double size) has no effect. Nothing is drawn. I need to change the drawn size because of the different dpi ... Where am I gong wrong ?
Edit: The solution seems to be simply to use the g.DrawImage method instead. Why imageList.Draw() doesn't draw is still a mistery to me ...
g.DrawImage(imageList.Images[imgIndex], bounds);
ImageList.Draw() is a bit unusual, it takes advantage of the built-in support that the native image list code inside of Windows has for rendering an image in the list. This is an optimization, it avoids the cost of converting the internal image as stored in the native image list back to a managed Image object.
One side-effect however is that this drawing happens without regard for any of the transforms that were applied to the Graphics object. A 16x16 image in the list is going to be rendered as 16x16 pixels on paper. Which is indeed a bit hard to find back, printers have very high resolution (600 dots per inch is typical), that image turns into a decimal point.
Image lists were really meant to be the source of images for the TreeView and ListView controls, it is not a good general purpose collection object for images. Like a List<Image>. Your workaround is good, the Image property converts the internal bitmap back to a managed Image, Graphics.DrawImage() will then scale it appropriately to get a size on paper that's close to the size on the screen. However with the graininess you get from making an image 6 times larger. Note that you should Dispose() that object.