I can't figure anyway to do this, I don't want to scale it with .Draw, I want to just change the width.
The best way is using .Draw particularly if you are scaling a lot, especially as your object should handle its own drawing capabilities.
You can render the texture using a render target at the size you want, and then saving the render target texture.
Searching for a quick code example came up with the following which is saying the same thing:
How to resize and save a Texture2D in XNA?
Related
Recently I thought: "Let's set the 'resolution' from 16:9 to 16:9(1920x1080)" but i noticed that now all my positioning* code was off, and the size of pictures and text was way too small.
My problem now is, if I should just use the 16:9 aspect ratio or an fixed resolution (I don't know the benefits). But if I shouldn't use the aspect ratio, how to change the fixed resolution when the Project is ready, for example in the settings, without needing to rewrite all my code* and rescale all my images on the Canvas according to the resolution.
*For those of you who don't know what I mean with 'positioning', I mean setting the position of an Image on the Canvas, which obviously needs to be changed because the resolution is different. You could make something that detects your resolution and positions you image based on that, but idk if there is a better solution.
The best way to do this is during positioning ui using procentage also canvas Type which is displayed to resolution.
https://youtu.be/Tys6QWi9RpM
Solution on yt.
I'm making an app for Windows 8.1 where it is important to be able to zoom in and examine images in detail. If I just open up the bitmap and zoom in it looks like.
However when I load the image into my app and use the ScrollViewer to zoom in I get.
As it appears to be trying to interpolate pixel values for some sort of anti-aliasing.
How can I get it so that when I zoom in it shows (as best it can) the exact pixels of the image? In particular I'm using the image as the background to a canvas which is contained in a scroll viewer.
I've looked around on here and MSDN and found a pair of related questions, but as yet they don't seem to have solved my exact problem.
A discussion on WPF
A similar issue with a canvas
Older related question on pixel art
A way to use bitmap encoding (which I couldn't get to work)
Similarly phrased question
There is no easy way to go about this, your best option is to use DirectX to render the image much larger so that you can mitigate the effect of WinRT automatically interpolating pixel values.
As someone explained on MSDN and based on this outstanding request I can't see any other way to accomplish this.
Use Win2D
Win2D is a DirectX inter-op library for WinRT. With this you can render the image at a much larger size, and then set the default zoom level for the scrollViewier to be very small. Because of this when you zoom in it will appear to be that you can see the individual pixels without any fuzzy/blurry interpolation because you will actually be seeing groups of 64 pixels or so all as one color. I couldn't find any way to actually override what kind of interpolation gets done so this seems to be the best method.
Download Win2D as a NuGet package using Visual Studio, Win2D's
quickstart guide does a good job explaining some of the setup
Set up your canvas and the draw event and use the DrawImage function to render the image larger
<ScrollViewer x:Name="Scroller" ZoomMode="Enabled"
MinZoomFactor="0.1" MaxZoomFactor="20">
<canvas:CanvasControl x:Name="canvas" Draw="canvas_Draw" CreateResources="create"/>
</ScrollViewer>
In the canvas_draw function.
canvas.Width = original.Width * 10;
canvas.Height = original.Height * 10;
args.DrawingSession.DrawImage(bitmap,new Rect(0,0,original.Width*10,original.Height*10), new Rect(0,0,original.Width,original.Height), 1.0f, CanvasImageInterpolation.NearestNeighbor);
Make sure to set your canvas to be larger as well
In your code behind set the default zoom of your ScrollVieiwer to be appropriate so your image appears to be the same size.
In the page constructor
Scroller.ZoomToFactor (0.1f);
Other Ways Which I Looked Into and Didn't Work
Making the canvas very large and using BitmapEncoder/BitmapDecoder with the interpolation mode set to NearestNeighbor, this introduced lots of visual artifacts even when scaled to a power of 2 size
Render options only appear to be usable in WPF and not WinRT
It may also be possible to use some image manipulation library to simply make the bitmap 10x or so as large and then use that, but I ended up using Win2D instead.
For some reason, everything I tried that was online about resolution independence doesn't really work the way I would want it to. Most of the solutions suggest a way to get the width and height and then use a class with them, but the result is always a cutoff picture(too big picture) or a picture in the top left corner with smaller height and width than those of the screen.
P.S. The game is in fullscreen, but we tried windowed and it didn't work either.
This is actually a pretty simple fix. Basically, create a RenderTarget object somewhere and do all your drawing to that object, then resize that to the screen.
Use GraphicsDevice.SetRenderTarget(target) to change the render target, then do all your drawing operations, then change it back to the back buffer afterwards by setting it to null. RenderTargets actually derive from Texture2D, so you can use it in as an argument, such as: SpriteBatch.Draw(renderTarget, Viewport.Bounds, Color.White), and this will stretch it to fit the screen.
I'm desperately trying to render images onto a 3D surface in WPF using nearest-neighbor sampling. Below is an example of what I currently have, in all its blurriness. The ImageBrush is given a 64x64 texture.
I've tried decorating the XAML with RenderOptions.BitmapScalingMode="NearestNeighbor" everywhere from the Window to the ImageBrush without fortune. I've tried writing a custom pixel shader, and couldn't get a satisfactory result. It even appears that I cannot set the texture sampler's filtering mode from within the shader code. I've considered work-arounds, such as scaling up the source texture myself, but this would still leave artifacts at two of the edges where it begins interpolating into the next pixel.
Bottom line: Is there any way I can accomplish the effect of nearest neighbor image sampling on a 3D model in WPF?
Just had the same problem, the answer in this thread provides a workaround.
You can use a VisualBrush with an Image then WPF will respect the BitmapScalingMode on the image. You can also set the CachingHint (also on RenderOptions) which might improve performance (did not measure it though).
var image = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/Resources/image.png")) };
RenderOptions.SetCachingHint(image, CachingHint.Cache);
RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.NearestNeighbor);
var material = new DiffuseMaterial(new VisualBrush(image));
That works for simple scenes, as I said I didn't measure the performance, but I imagine the VisualBrush will hurt for bigger stuff (compared to an ImageBrush). Personally I'll switch over to Direct3D interop and render the scene via SharpDX when I hit that problem.
The project I'm working on requires the ability to transform any of the 4 corners of an image. As GDI+ unfortunately doesn't have this capability, we're resorting into using DirectX's 3D graphics.
While I have a square mesh with a texture showing successfully on-screen, I need to be able to generate an image from this rendering, with the background set to transparent. Is there a way to efficiently achieve this?
Preferably, I'd like to do this without using a Control for initializing a device. Alternatively, I don't mind the option of creating a custom, invisible Control that will generates an image for me.
Edit:
Actually, I just realized a transparent background is strictly not necessary, but it would help the performance of our project a bit.
Anyway, I've had some luck doing something like this, but it is excessively slow. Perhaps there's a better method?
// Create a surface to render an image to
Surface mSurface = mDevice.GetRenderTarget(0);
// Render the visualization
mDevice.Clear(ClearFlags.Target, Color.Transparent, 1.0f, 0);
mDevice.BeginScene();
/* Do some amazing stuff */
// Exit rendering
mDevice.EndScene();
mDevice.Present();
// Render the bitmap images
GraphicsStream mGraphics = SurfaceLoader.SaveToStream(
ImageFileFormat.Bmp, mSurface);
Image mImage = new Bitmap(mGraphics, false);
Well if you use D3D for doing the final rendering to screen then you can easily do the things you are talking about using render-to-texture.