I founnd some strange behaviour with image control in wpf
I have issue with image control. Image is rotated automatically.
I want it to be shown as original.
<ImageEdit x:Name="root" Source="/Images/DSC_0100_VerticalOrigation.JPG" />
Devexpress ticket link
Can anyone help me with this.
This code is working for this
void Rotate(Bitmap bmp)
{
if (pi == null) return;
byte o = pi.Value[0];
if (o==2) bmp.RotateFlip(RotateFlipType.RotateNoneFlipX);
if (o==3) bmp.RotateFlip(RotateFlipType.RotateNoneFlipXY);
if (o==4) bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
if (o==5) bmp.RotateFlip(RotateFlipType.Rotate90FlipX);
if (o==6) bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
if (o==7) bmp.RotateFlip(RotateFlipType.Rotate90FlipY);
if (o==8) bmp.RotateFlip(RotateFlipType.Rotate90FlipXY);
}
Related
I'm starting in WPF and I'm developing an application that has a background (.png) applied as follow:
'<Border.Background>'
'<ImageBrush ImageSource="final.png" AlignmentY="Top"/>'
'</Border.Background>'
No problems until here. My problem is because I have an Expander in my window and, in my collapsed method I make an alteration in window size, as shown:
private void Expander_Collapsed(object sender, RoutedEventArgs e)
{
windowFrame.Height = 400;
}
I would like that image, used as background, stay fixed after expander action, ie, when the window is expanded the background is shown full, and when is Collapsed the background shall be cutted.
In analogy to c#, is similar like BackgroundImageLayout = none. You can redim your WindowsForm and the image will be showing according to windows size.
I need finish this job and I hope find my answer here.
Thanks a lot!
<ImageBrush ImageSource="final.png" AlignmentY="Top" Stretch="None"/>
The default value for Stretch is "Fill"
I have a bitmap image in an image control
I need to draw a red line on the bitmap each time I click with the mouse onto it, at the place where I clicked the mouse.
I first thought of creating a Line object, but found out, that I cannot add the Line. I would need a canvas. But if I put my image in a canvas, my bitmap does not stretch over the whole canvas (I found out, that the coordinates of the bitmap determine the place on the canvas, so my bitmap is wrongly displayed.)
Then I tried using graphics
Graphics graphics = Graphics.FromImage(bitmapImg);
graphics.DrawLine(new System.Drawing.Pen(System.Drawing.Color.Red), 0, 0, bitmapImg.Width, bitmapImg.Height); //not the line yet, just for testing
graphics.DrawImage(bitmapImg, 0, 0, bitmapImg.Width,bitmapImg.Height);
graphics.Dispose();
However, I don`t get anything painted onto my bitmap........
Now I think, I probably have to get the bitmap into an array and then change the pixel color to get the line in the bitmap. I believe, that this would be very slow.
I am now trying something with visualDrawing, however, I have not got it to work yet:-(
What is a good way to get a line onto an existing bitmap in WPF C#???? and how to remove it?
I would be glad for any help! Thank you! I posted it already on the MS forum page, but no answer so far.
When you do Graphics.FromImage, this Graphics class (and also the System.Drawing.Pen) do not belong to WPF, they are part from WinForms and they are internally using Windows' GDI+ calls to draw and cannot draw on top of WPF.
If you didn't got an error when compiling the first line of your code, then probably your bitmapImg is a System.Drawing.Image (from WinForms) not an Image control from WPF (System.Window.Controls.Image).
As adrianm mentioned, the easiest way will probably be to use a Grid:
<Grid>
<Image Source="your image" />
<Line Name="line" Visibility="Hidden" Stroke="Red" StrokeThickness="1" />
</Grid>
Then, in your click event handler you can make the line visible and give it the coordinates you want:
line.Visibility = Visible;
line.X1 = mouse_x;
line.Y1 = mouse_y;
line.X2 = ...;
line.Y2 = ...;
You can place a canvas with the background as transparent on top of your BitmapImage and then draw the line as required.
Code from xaml file:
<Grid>
<Image Source="C:\Users\sm143444\Desktop\download.jpg" />
<Canvas Background="Transparent" x:Name="draw" />
</Grid>
Code from Xaml.cs:
public MainWindow()
{
InitializeComponent();
Point startPoint = new Point(50, 50);
Line newLine = new Line();
newLine.Stroke = Brushes.Black;
newLine.Fill = Brushes.Black;
newLine.StrokeLineJoin = PenLineJoin.Bevel;
newLine.X1 = startPoint.X;
newLine.Y1 = startPoint.Y;
newLine.X2 = startPoint.X + 100;
newLine.Y2 = startPoint.Y + 100;
newLine.StrokeThickness = 2;
this.draw.Children.Add(newLine);
}
output
Or you can even add a ZIndex to your image and Line so that they are laid on different layers on canvas.
I use on listbox control own datatemplate. Listbox item consist one image control and some textblock.
On image source I bind property type of Uri (absolute url - for example: http://u.aimg.sk/fotky/1730/71/17307141.jpg?v=2)
Listbox have about 50 - 300 items.
If I test app, I sometimes see blank - white or black image instead user images.
The problem you can see on this images:
I would like to know what cause this problem and how can I solve this problem.
Image sources are good, I check it in browser.
Thank for advice.
I think what's happening is a race condition. Some of your images haven't completed downloading by the time you are asking them to display. There is a pretty good example given here http://social.msdn.microsoft.com/Forums/en/wpf/thread/dc4d6aa9-299f-4ee8-8cd4-27a21ccfc4d0 which I'll sum up:
private ImageSource _Src;
public ImageSource Src
{
get { return _Src; }
set
{
_Src = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Src"));
((BitmapImage)_Src).DownloadCompleted += new EventHandler(MainWindow_DownloadCompleted);
}
}
void MainWindow_DownloadCompleted(object sender, EventArgs e)
{
PropertyChanged(this, new PropertyChangedEventArgs("Src"));
((BitmapImage)_Src).DownloadCompleted -= MainWindow_DownloadCompleted;
}
With the above code, your images that are binding to your property will be told to update with the PropertyChanged call when the value is first assigned as well as AFTER the images have downloaded 100%. This is taken care of in the DownloadCompleted event handler that is utilized in the above example. This should make them not appear as a black image anymore, but as their fully-ready selves.
Also, if you are using a stream to as the source for your images, you need to make sure you use BitmapCacheOption.OnLoad. Such as:
BitmapImage source = new BitmapImage();
source.BeginInit();
source.CacheOption = BitmapCacheOption.OnLoad;
source.StreamSource = yourStream;
source.EndInit();
This is because by default the image using the source will lazy load it and by then your stream is probably closed, which could also be why you get blank/black images.
Good luck.
I'm using WPF in WinForms with ElementHost. When the form loads, there is a flash of black background where the ElementHost is about to load. This looks kind of bad. Any suggestions on how to get rid of this?
Hide the element (Visibility = Hidden) until the WinForms control is fully loaded...
I know this has already been answered and the question is old but none of the presented answers worked for myself and after a long time of troubleshooting the issue. I finally found an easier answer.
If you build a class extending from Element Host and in the initial constructor. You can set a Load Event for the Host Container. The Host Container is the panel that the Element Hosts Child is being displayed on top of. From there, just set the Host Containers background color to being of the Element Hosts Parents background color.
Like this
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;
public class MyElementHost : ElementHost
{
public MyElementHost()
{
this.HostContainer.Loaded += new RoutedEventHandler(HostPanelLoad);
}
public void HostPanelLoad(object sender, RoutedEventArgs e)
{
System.Drawing.Color parentColor = this.Parent.BackColor;
this.HostContainer.Background = new SolidColorBrush(Color.FromArgb(parentColor.A, parentColor.R, parentColor.G, parentColor.B));
}
}
you need first show control with empty bounds first time to avoid black flickering
if (!_control.Created && _control.BackColor != Color.Transparent)
{
_control.Bounds = Rectangle.Empty;
_control.Show();
}
// set control bounds and show it
Rectangle bounds = GetBounds(context, rect);
if (_control.Bounds != bounds)
_control.Bounds = bounds;
if (!_control.Visible)
_control.Show();
When I display a JPEG in my WPF application (using the following code), it is shown significantly smaller than if I open the JPEG in the Windows Picture Viewer at actual size.
I've drilled into the properties of my ImageSource at runtime and my image has:
a DPI of 219
a Height of 238.02739726027397
a Width of 312.54794520547944
a PixelHeight of 543
and a PixelWidth of 713
When I use a screen ruler to measure the WPF display of the image, I get approx. 313x240 pixels (which if I could positiont the ruler perfectly would probably be equal to the Width and Height that the ImageSource is reporting.).
My gut tells me this has something to do with WPF's use of device independent units (instead of pixels) but I can't make sense of it, and I still need to know how to display the image at the 'actual' size of 543x713 in my application.
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<StackPanel>
<Image Source="Image15.jpg" Stretch="None" />
</StackPanel>
</Window>
Thanks Mark! I did some Googling based on your info and found this article that provided a solution to get the result I wanted. This is starting to make sense now...
Edit: Linkrot. Pasting the critical text from the article here for reference....
<Image Source=”{Binding …}”
Stretch=”Uniform”
Width=”{Binding Source.PixelWidth,RelativeSource={RelativeSource Self}}”
Height=”{Binding Source.PixelHeight,RelativeSource={RelativeSource Self}}” />
Here we’ve set Stretch to Uniform and bound the Width and Height to the PixelWidth and >PixelHeight of the Source, effectively ignoring DPI. The image however will not be pixel >perfect, even when using SnapToDevicePixels (which simply snaps the borders, not pixels >within the image). However, WPF in 3.5 SP1 will support a NearestNeighbor >BitmapScalingMode, which should correct this.
Use a DPI of 96. WPF is scaling your image based on the size in inches, while the image viewer is displaying pixels. On most Windows systems, the screen resolution is assumed to be 96 DPI, so using that in your image will result in a one-to-one translation.
Alternatively, you could extend Image and implement MeasureOverride and ArrangeOverride to change the effect of the image's DPI:
class DpiAgnosticImage : Image
{
protected override Size MeasureOverride(Size constraint)
{
var bitmapImage = Source as BitmapImage;
var desiredSize = bitmapImage == null
? base.MeasureOverride(constraint)
: new Size(bitmapImage.PixelWidth, bitmapImage.PixelHeight);
var dpiScale = MiscUtil.GetDpiScale(this);
desiredSize = new Size(desiredSize.Width / dpiScale.Width, desiredSize.Height / dpiScale.Height);
desiredSize = ImageUtilities.ConstrainWithoutDistorting(desiredSize, constraint);
if (UseLayoutRounding)
{
desiredSize.Width = Math.Round(desiredSize.Width);
desiredSize.Height= Math.Round(desiredSize.Height);
}
return desiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
return new Size(Math.Round(DesiredSize.Width), Math.Round(DesiredSize.Height));
}
}
Use it in xaml as if it were an Image:
<Grid>
<local:DpiAgnosticImage
Stretch="None"
Source="{Binding ViewImage}">
<Image.RenderTransform>
<ScaleTransform
x:Name="SomeName"/>
</Image.RenderTransform>
</local:DpiAgnosticImage>
</Grid>
Flaws to above code (that I know of):
Ignores Stretch
Assumes Source is a BitmapImage
=== Edit - Will's comment suggests he would like to know what is in GetDpiScale()
public static Size GetDpiScale(Visual visual)
{
var source = PresentationSource.FromVisual(visual);
var dpiScale = new Size(
source.CompositionTarget.TransformToDevice.M11,
source.CompositionTarget.TransformToDevice.M22);
return dpiScale;
}
This is the result of the .jpg file itself specifying the DPI - WPF is simply obeying. Here is a forum post detailing the problem with some solutions: