Different images are printed as same image using PrintVisual - c#

I'm using PrintDialog.PrintVisual() to print my viewmodel. For this I use binding on a dictionary:
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="329" Height="204">
<Image Source="{Binding Details.Properties[Imagedata].ImageStream}" Stretch="Fill" Width="95" Height="122" Canvas.Left="14" Canvas.Top="41"/>
<Image Source="{Binding Details.Properties[Signature].ImageStream}" Stretch="Fill" Height="25" Width="100" Canvas.Left="122" Canvas.Top="143"/>
</Canvas>
If I put this Canvas on my WPF window, it's showing fine. But if I want to print it, it's using the first image on my second image. In debugger I checked after UpdateLayout the Image.Source - both are right. The next step is PrintDialog.Printvisual(canvas, "print"); The output is as described but not the same every time. Sometimes the first image is even repeated in the second Image.
Why does this happen?
UPDATE: I found a workaround: I search for all Image elements, copy the ImageSource into a MemoryStream and create a new BitmapImage out of it. It's not nice, but it works right now. If anybody could explain, why this works, it would be great.

Related

WPF Bitmap transparent background turns black

I have a listbox with Items that all have a random background color.
In each Item of the listbox i want to display a Bitmap picture.
Now for some reason the background of each bitmap (which I've set to Color.Transparent) Shows up black.
Here a picture of how it looks
My code for the listbox:
<WrapPanel Grid.Row="1" Grid.Column="1" Margin="6" >
<ListBox x:Name="CharListBox" BorderThickness="0" ScrollViewer.VerticalScrollBarVisibility="Hidden"
ItemsSource="{Binding ListToDisplay, UpdateSourceTrigger=PropertyChanged}"
ItemTemplate="{DynamicResource ItemTemplate1}"
SelectionChanged="SelectionChangedNewCharSelected">
</ListBox>
</WrapPanel>
The item template (I removed everything beside the image part for bettter overview):
<DataTemplate x:Key="ItemTemplate1" >
<Image Source="{Binding OutfitImageSource, UpdateSourceTrigger=PropertyChanged}" Height="40" Width="40" />
</DataTemplate>
The Binding binds to a BitmapSource.
Is it possible that bitmaps dont have actual transparency, its just shown as black?
I also tried to add AllowsTransparency="True" to the window properties, this just lead to the window crashing instantly..
Thank you for helping in advance!
update: AllowsTransparency works if i set WindowStyle="None" but it still does not fix the problem with the untransparent bitmaps.
As reported in this answer
Bitmaps (i.e. files with .BMP extension) do not natively support transparency: you need to save as a different format like PNG.
You can find the same info also here.
So it does not depend on your XAML or your code. Just save your bitmaps as PNG files and then use those files for your application.

How can i convert a 22bpp gif image to a 32bpp gif image in C#?

I am using picturebox control in WPF to show a Gif image. Since i am using AllowTransperency="True", picturebox control is not getting displayed. As per this stackoverflow article i have to convert my 22bpp image to 32bppimage. How can i do that? Kindly advice.
<Window Loaded="Window_Loaded" VeritcalAlignment="Center" AllowTransperency="True" Background="Transparent">
<border Background="Transpernt" BorderThickness="0">
<Grid>
<wfi:WindowsFormsHost Grid.Row="4" HorizontalAlignment="Center" VerticalAlignment="Center">
<winForms:PictureBox x:Name="myImage"></winForms:PictureBox> </wfi:WindowsFormsHost>
Code Behind
myImage.Image = #"C:\MyImage.Gif";
Please help. Thanks a lot for your help and time in advance.
Take a look at GifBitmapEncoder. One solution would be iterate over each frame and convert each bitmap.
Also, take a look at NGif, an open source library. It may suit you needs more.

When reading from a file stream image get flipped -90

I'm trying to load an image in a local path to a Silverlight image control. This is an out of browser application. When I load the image using a stream it's always flipped upside down.
Any idea why? This happens for large images only.
FileName here gives the full path to local file system, like C:\imageFullPath\image.jpg.
Please help. Following is the code.
------ In Model side------------------------
public BitmapImage DisplayImage
{
get
{
if (!string.IsNullOrWhiteSpace(FileName))
{
var b = new BitmapImage();
b.SetSource(System.IO.File.OpenRead(FileName));
return b;
}
return null;
}
}
------ In Silverlight View side------------------------
<Image Source="{Binding DisplayImage, Mode=TwoWay}" Width="450" Height="250" Margin="0,0,0,0"/>
What i see when debugging
BMP are normally stored "upside-down" with the pixels in reverse order from bottom to top, but can use a negative height in the file header to indicate the image is stored top-to-bottom, so perhaps you have such an image.
Does this happen with all images, or just that one?
You could try changing the way the image is loaded, using a Uri in the constructor instead of calling SetSource() with a Stream, as it may account for the header and read the file differently:
var b = new BitmapImage(new Uri(FileName));
return b;
Or, if that doesn't help, you can apply a transform to flip every image, but that doesn't solve the underlying problem:
<Image Source="{Binding DisplayImage, Mode=TwoWay}" Width="450" Height="250" Margin="0,0,0,0">
<Image.RenderTransform>
<ScaleTransform ScaleY="-1" />
</Image.RenderTransform>
</Image>

How do I get a ScrollViewer with a Rectangle inside to stop scrolling when it reaches the end of the rectangle?

I have created a Rectangle inside of a ScrollViewer like this
<ScrollViewer ManipulationMode="Control" x:Name="songScrollViewer" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled" Height="270" VerticalAlignment="Center" Width="728" Canvas.Top="20" d:LayoutOverrides="HorizontalMargin" >
<Rectangle x:Name="musicBG" Fill="#FF0692FD"/>
</ScrollViewer>
During the use of the app, the size of MusicBg changes, sometimes to something around 3,000 pixels width.
musicBG.Width = _songLength*PixelsPerSecond
However, while scrolling the scrollViewer, it allows me to scroll the rectangle all the way off the screen.
For example this line of code gives me the following values when I have moved the rectangle as far as I want to move it.
if (songScrollViewer.HorizontalOffset > songScrollViewer.ScrollableWidth)
HorizontalOffset has a value of ~1200 and ScrollableWidth has a value of about ~2900.
How can I get this to be done properly so that the rectangle is not scrolled completely off the screen?
I would expect a HorizontalOffset of about 1200 to only push the rectangle about halfway through to it's destination, and not make it start going off screen.
ANSWER:
After much frustration, I was able to solve this problem by using Canvas instead of Border or Rectangle.
I'll award points if anyone can explain why this problem happened, and if there is a less processor intensive control that would work better than canvas.
Edit: Screen shots:
Bad Code:
<ScrollViewer ManipulationMode="Control" x:Name="songScrollViewer" Width="720" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled" Height="270" VerticalAlignment="Top" Canvas.Top="20" HorizontalAlignment="Left" >
<Border x:Name="musicBG" Background="#FF0692FD" VerticalAlignment="Top" HorizontalAlignment="Left" Height="270" />
</ScrollViewer>
Image of bad scroll with bad code:
Good working code:
<ScrollViewer ManipulationMode="Control" x:Name="songScrollViewer" Width="720" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled" Height="270" VerticalAlignment="Top" Canvas.Top="20" HorizontalAlignment="Left" >
<Canvas x:Name="musicBG" Background ="#FF0692FD" Height="270" >
<Border Background="#FF0692FD" VerticalAlignment="Top" HorizontalAlignment="Left" Height="270" />
</Canvas>
</ScrollViewer>
Good Scroll: Notice it says 170 seconds on the bottom right instead of the smaller number of 118 seconds in the bad scroll.
I believe your right, wp7 won't render shapes that are bigger then 2048 pixels. So the reason it's scrolling of the page is because it's treating it as if it were bigger then 2048 but you can only see up to a width of 2048px and its just scrolling over to the "ghost" part of the rectangle.
I'm not sure if you can override this but the best solution I could come up with (without overriding) is by splitting up your rectangle into chucks that are smaller then 2000 (just to be safe) and then displaying them seamlessly in a horizontal stack panel inside the scroll viewer. The problem with this is that depending on how you've coded it, this solution might be hard to implement; but you might just be able to split it in your ViewModel when displaying it and your logic would only see it as one big chunk.

Is there any default strategy to prepare application for a resolution change?

How to prepare a Silverlight or WPF application to change from a big resolution to a small resolution?
I guess using dockpanel strategy only works for changing from a small to a big resolution.
So, is there any default strategy? Thanks.
Problem: I have a button the ends in the pixel 1024, 768. And I change the resolution to 800x600.
Some time ago I had a similar issue. As a workaround I surrounded the window content in a Viewbox.
Users that used 1024x768 instead of 1280x1024 see the application content smaller, but they preferred this than scrolling all the time. (WPF)
I'll have to work on this for our next project, let's hope somebody has better ideas!
Well, you could design your layout to Stretch and designing it with 800x600 in mind, so whenever the layout becomes larger than 800x600 it will fit. But...
if you really want something fancy, detect the change in the window size/ActualHeight and ActualWidth (using SizeChanged) then scale the the application according to size via code (using dynamic transforms).
For example, in the "LayoutRoot" in your main view:
var x = new ScaleTransform();
x.ScaleX = .5; // Do fancy computation here
x.ScaleY = .5; // Do fancy computation here
this.LayoutRoot.RenderTransform = x;
Just an idea, i mean if the screen is bigger than your design you enlarge and vice versa.
Hope this helps.
I think doing this way is better:
ScrollViewer Background="GreenYellow" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" Name="layoutRoot">
Canvas Width="1024" Height="768">
dataInput:Label Height="50" Name="label1" Width="100" Canvas.Left="540" Canvas.Top="131" Content="aeeeeeeee" />
Button Canvas.Left="12" Canvas.Top="131" Content="Button" Height="23" Name="button1" Width="75" />
Button Canvas.Left="937" Canvas.Top="147" Content="Button" Height="23" Name="button2" Width="75" />
Button Canvas.Left="510" Canvas.Top="21" Content="Button" Height="23" Name="button3" Width="75" />
Button Canvas.Left="482" Canvas.Top="550" Content="Button" Height="23" Name="button4" Width="75" />
/Canvas>
/ScrollViewer>

Categories

Resources