Replace an image when clicked - c#

Not sure if the title makes any sense.
In my WPF application I would like the window to contain a small image, icon size. When the user clicks on the image another one simply replaces it, that holds the same dimensions.
I have all the images loaded into my project for C#/WPF. (By the way there are 3 images)
What I have been trying:
I tried changing the opacity in the code-behind to make one image
have full opacity and the others have no opacity. Didn't work as the
first toggle would strangely make all images disappear.
I also tried dynamically changing the image source in the code-behind. I
used if statements and a field to determine what image to switch
the source to. Code being:
if (toggle == 1)
{
thebutton.Source = new BitmapImage(new Uri(#"/images/icon2.png", UriKind.Relative));
toggle = 2;
}
Also did not work (made it blank, rather than switching to another image) but I feel like there is an obvious way I'm not seeing.
What I initially wanted to do was simply (like in graphics programs) raise and lower the images to the top and bottom to determine which ones the user should see. All that matters is the visual. The user clicks image 1, image 1 disappears and image 2 appears in its place, and so on for image 3.

Set the Build Action of the image files to Resource, and load them by Resource File Pack URIs:
thebutton.Source = new BitmapImage(new Uri("pack://application:,,,/images/icon2.png"));

Related

Image shrinking in a label of c# win forms

I am designing a c# .NET 4.5 win form.While inserting an image in a label, the image is behaving differently.I have two labels and i insert 2 different image in them.In the first one, i am setting image using an Image property and in the second one, i am just using the ImageList.Now the funny thing is that for the second label, its image is shrinking while for the first label its not. Why is it happening so??Please advise. Image is attached herewith for better understanding:
In the image, you can see that image of first label is showing correctly, while that of second label not
The issue is that the Image and ImageList properties work pretty differently. While for the Image, it will display the image as it is, ImageList has a property called ImageSize. This property affects the size of the stored images in the Label ImageList at compile time such that all images in the ImageList will have the size of ImageSize in the runtime.
Your image shrinking in when you use ImageList is likely caused by this. The default value of ImageSize is 16x16.
And you also cannot change the ImageSize at runtime, since it will be like replacing the list, all images will not be displayed(!).
So, if you display your images using ImageList, all your images must be of the same size. Or else, you have to put your images in the Resources.resx such that the image size will not be changed and somehow access to the images there at run time.

How to display scaled image without anti-aliasing?

Question
How can I scale an image in XAML quickly without anti-aliasing applied?
Background
I am trying to make a pixel editor as a Windows 8 XAML/C# app. I'm using c#/XAML because most of my experience is with c#/WPF.
Method 1: WriteableBitmap + Image control. Originally, I used a WriteableBitmap to store and edit an image. That image is displayed in a resized XAML Image control. The problem is that the image does not get scaled properly because of anti-aliasing. (XAML does not seem to provide the BitmapScalingOptions that are available in WPF)
Method 2: Redrawn WriteableBitmap + Image control. Next I tried writing my own scaling, where I take my original image and write to a larger WriteableBitmap so that the scaled image is pixelated. The scaled image is then presented inside a XAML Image control. This process is slow and inefficient.
Method 3: SharpDX + Direct2d ?? I am pretty sure a solution exists somewhere between SharpDx, SurfaceImageSource, and Direct2d. Event still, I can't quite figure out how to display a SharpDx.WIC.Bitmap inside a Windows.UI.Xaml Image control, and am generally getting lost in the documentation.
What exactly is a recommended setup for achieving my desired end? Are there c# samples available which might point me in the right direction?
I don't know if you mean by scaling it by resizing it with the mouse or just with a button click to auto scale to a predetermined size.
But the thing you can do is to use an Image panel and then, just set it to image.Stretch = Stretch.Fill; so if you override and create a method for the Resize event of the Image Panel, your image will take the size to fill the Image panel.

Save Image in PictureBox with overlapping Controls

I am developing an application in which user can select an image in a picture box.
After that he can right click on the image and add a user control which will again display an Image along with some text. This user control can be added any number of times.
User can also re-position the user controls as per need.
All this functionality has been implemented and is working fine.
Now, the requirement is to save the Image along with the user control.
Above you can see the complete image which needs to be saved. Back image is the picture box image and the user control (small images with text).
When user will click on save button the image should get saved on his disk as a single image.
This is a windows application developed in C#.
I want to know that whether this functionality can be achieved or not. If yes, then please guide me in the right direction.
If you create a copy of the bitmap then with the Graphics.DrawImage() you can draw those images onto it. You need to calculate the position of those controls.
Look here for DrawImage: http://msdn.microsoft.com/en-us/library/42807xh1.aspx
example:
Bitmap copy = new Bitmap(OriginalBitmap);
Graphics g = Graphics.FromImage(copy);
g.DrawImage(arrowBitmap, new Point(..));
copy.Save(...);
A very simple and straight forward solution exists, has been thought of by Microsoft and includes these steps:
Instead of PictureBox use a Panel and instead of using the Image property of the PictureBox use the BackgroundImage property of the Panel
note: By using also the BackgroundImageLayout property you can quite easily instruct the Panel to stretch, center or zoom the image (I'm presuming the default value which is tile is not a good option in your case)
Instead of placing the other user controls at higher Z order but alongside the previous PictureBox place them inside the Panel
Use the Control.DrawToBitmap method like so:
private void button1_Click(object sender, EventArgs e) {
var bmp = new Bitmap(this.panel1.Width, this.panel1.Height);
this.panel1.DrawToBitmap(bmp, new Rectangle(Point.Empty, bmp.Size));
bmp.Save(#"D:\test.png", ImageFormat.Png);
}
That will result in your controls begin rendered along with the picture:
Furthermore, and if your scenario allows it, you could simply use the DrawToBitmap method with any control which contains all of the actors you wish to render, for instance the actual Form.

windows phone image overlay

I want to know how to overlay one image over the over in Windows Phone. I did some search online, a lot of people suggest put two images into one grid and adjust the margin. However, my case is a little different. I'm making the background image of the secondary tile, I want to integrate the two images, store it locally and make the tile. So I can't put them into a grid. So what should I do in this case? Thanks!
You can create UserControl with any layout you wish (173x173px). Then, when you need to generate a tile, put this control to a page (probably out of the screen) and make and image from it with new WriteableBitmap(YourTile, null);. Than save these image to the /Shared/ShellContent/ and you are done
Probably there are better solutions for this task but this works fine too
I made this work using Ku6opr method using the following
WriteableBitmap bmp = new WriteableBitmap(173, 173);
bmp.Render(renderRoot, new TranslateTransform());
bmp.Invalidate();
where renderRoot is the usercontrol containing the Grid and the Image. I then save the bmp to the /Shared/ShellContent folder in Isolated storage.

Odd behaviour of Image control in WPF

I'm trying to get started with WPF in c#.
I set a Canvas as the content of a window, then I create another Canvas and put it as a child of the first Canvas (together with other elements, such as buttons and labels). Everything runs fine until I create an Image object and add it dynamically to the inner Canvas:
Image m_Img = new Image
{
Name = "img1",
Width = cvWindow.Width,
Height = dUsefulHeight,
Stretch = Stretch.Uniform
};
m_Img.Source = new BitmapImage(
new Uri(xMap.SelectSingleNode("#image").FirstChild.Value,
UriKind.RelativeOrAbsolute));
Canvas.SetLeft(m_Img, 0);
Canvas.SetTop(m_Img, 0);
double d = m_Img.Source.Width;
cvWindow.Children.Add(m_Img);
Here m_Img is the image I create, cvWindow is the inner Canvas. The source of the image is a PNG file, extracted from an XML file (the string returned is correct).
The odd behaviour is here: if I comment out the line
double d = m_Img.Source.Width;
the Image is not displayed anymore, although other controls in the Canvas (such as labels and buttons) are correctly displayed.
I don't need the width of the source image, so the compiler tells me that variable is never used.
I updated Visual Studio 2010 to the last SP1, but the behaviour remained. Google doesn't help either. I came to think that the Width property may have a getter method that triggers some action, but cannot solve the puzzle.
Edit: Same thing happens using another property of Source (e.g. Height). If I access at least one property, the image displays ok.
I finally discovered what happens: the Image control needs that the properties DecodePixelWidth and DecodePixelHeight of the Source are set to the correct values.
Once the Source is created, those values are not set, and the Image is not drawn. Upon first access to any property of the BitmapImage that serves as source the image is actually decoded and those properties are set to the final width and height of the decoded image (so the Image can be drawn).
I can solve this by setting those values by hand (with a cast to int) like this
BitmapImage bs1 = new BitmapImage();
bs1.BeginInit();
bs1.UriSource = new Uri(
xMap.SelectSingleNode("#image").FirstChild.Value,
UriKind.RelativeOrAbsolute);
bs1.EndInit();
bs1.DecodePixelHeight = (int)bs1.Height;
bs1.DecodePixelWidth = (int)bs1.Width;
m_Img.Source = bs1;
but I think I will re-design my views with a better separation (views in XAML, model and viewmodel via code).
This bit is also mentioned in the second note in http://msdn.microsoft.com/en-us/library/ms747027.aspx
When you specify the size of an image with either Width or Height, you should also set either DecodePixelWidth or DecodePixelHeight to the same respective size.
Don't define your views via code - use XAML,
even if you are trying to creating dynamic views, using XAML is much more clean
and using a good designer app (e.g. Blend), you'll notice things that you didn't consider.
Some things that you didn't consider are that .Width is not necessary equal to .ActalWidth.
Default widths are usually double.NaN (which means auto-width).
Use bindings, bind width of A to width of B, use margin, padding or value converters to make width A binded to width of B - const.
Use layout panels (e.g. Grid, StackPanel, DockPanel) to make alignment of multiple controls simple (and binding free).
Also, prefer using standard naming conventions (e.g. no m_).

Categories