Resizeing image (png) in windowsphone xaml without losing quality - xaml

In a listbox , i show flag icon for every row . and i use xaml image control in template of listbox item.
after resizing the png files ( flag icons ) , they lose their quality and they are not smooth any more ... what should i do with this problem ? for example in wpf there is a property RenderOptions.BitmapScalingMode for managing the quality . but i did not see anything in windows phone ... i was wondering if you guide me how can i fix this issue.
Thanks a lot
<Image Source="{Binding Icon}" Height="50" Width="50" Stretch="Fill" Margin="0,10,0,0"/>

RenderOptions.BitmapScalingMode does not exist in Windows-Phone.
But if you really want to do this code wise without vector images you can do it using Phone 8.1 SDK
Check out BitmapEncoder class. BitmapEncoder as part of the Windows.Graphics.Imaging Namespace.
BitmapEncoder.BitmapTransform.InterpolationMode is what you're looking for.

You could use the Bitmap to deliver the image with the same quality:
Image image = new Image();
Uri uri = new Uri(“images/single-pink-rose.png”, UriKind.Relative);
ImageSource img = new System.Windows.Media.Imaging.BitmapImage(uri);
image.SetValue(Image.SourceProperty, img);
Refer here for more: How to Reduce Size of Image in windows phone
How do I resize a BitmapImage to 50x50 on Windows Phone 7?
Hope it helps!

Related

How to set a background image with XAML/.NET Maui that has AspectFill behavior but left aligned?

I am working an app that uses an image as its background, and I want it to fill the entire window regardless of size. The image source is square-ish, like this:
The simplest way to do this is using AspectFill like this:
<Image
Source="image_source.png"
Aspect="AspectFill"/>
But that results in the image being centered, like this:
When what I need is for the image to be left aligned, like this:
I almost had some success using this:
<AbsoluteLayout>
<Image
Source="image_source.png"
AbsoluteLayout.LayoutFlags="HeightProportional"
AbsoluteLayout.LayoutBounds="0,0,Autosize,1"/>
</AbsoluteLayout>
but the problem there became when I had a screen like a tablet or foldable which is wider horizontally, it ended up getting letterboxed like this:
When what I would want would just be a regular AspectFill like this:
Is there any way to get this behavior with the existing Aspect options? If not, is there a way to extend the Aspect enum and the Renderer to make the image perform the same as AspectFill, but locked to the left edge of the image instead of the center?
I'm using XAML with .NET Maui, so if there is a solution in C# I'm open to that too
Was able to get a solution from Reddit, so I'm posting it here for anyone who stumbles across this:
My final XAMl ended up being
<Grid>
<Image
x:Name="backgroundImage"
Source="image_source.png"
Aspect="AspectFill"
HorizontalOptions="Start"/>
</Grid>
And I added this to the code-behind:
protected override void OnSizeAllocated (double pageWidth, double pageHeight) {
base.OnSizeAllocated(pageWidth, pageHeight);
const double aspectRatio = 1600 / 1441.0; // Aspect ratio of the original image
backgroundImage.WidthRequest = Math.Max(pageHeight * aspectRatio, pageWidth);
}

Image translation is clipped (how to prevent)

How can I force a UI object to NOT be clipped when it's partly outside the screen. I have an image that doesn't fit inside the screen completely. When I drag it (TranslateY) it moves like it's supposed to but the problem is that the part that was outside the screen doesn't appear so the image is abruptly cut. The only part of the image that is visibly moving is the part that originally fit to the screen.
Ps. Please do not recommend scollviewer as this is about a gesture to do a specific thing on the UI and ScrollViewer is not ok for that.
This is basically the XAML (The image is twice the height of the display)
<Grid x:Name="GestureScreen" ManipulationMode="TranslateY" RenderTransformOrigin="0.5,0.5">
<Image x:Name="GestureImage" CacheMode="BitMapCache" Source="Assets/bg/draggable.png" />
</Grid>
This is the C# (not really relevant, but still)
void GestureScreen_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
move.Y += e.Delta.Translation.Y;
}
Specify a row and column for the image which directly specifies Auto for both. That way the image will size to its actual size and not the current size of the * defaults of the screen size. Hence you will have the whole image as dragged.

WebBrowser control not showing last 2 lines of local HTML file

I have a WebBrowser control that's loaded with a local HTML file, like so:
var rs = Application.GetResourceStream(new Uri("View/Help.html", UriKind.Relative));
StreamReader reader = new StreamReader(rs.Stream);
browser.NavigateToString(reader.ReadToEnd());
reader.Close();
It displays fine, except the last two lines are cropped off. It's like the viewport of the WebBrowser isn't large enough (I can pull up and see the last two lines, but when I let go it bounces back down). The HTML file is fairly long, maybe 5 screens worth.
The XAML for the page is super simple, the entire page is the WebBrowser control:
<Grid x:Name="LayoutRoot" Background="Transparent">
<phone:WebBrowser x:Name="browser" Width="480" Height="800" IsScriptEnabled="True"/>
</Grid>
Any ideas?
If you've got the ApplicationBar visible then you'll need to reduce the size of your WebBrowser otherwise you'll be displaying content underneath the app bar.

ViewFinder Orientation With Windows Phone 7 Mango PhotoCamera

I am using the PhotoCamera control with the Windows Phone 7 Mango Beta 2 development tools.
The "ViewFinder" for the camera control is a rectangle object filled with a VideoBrush, as in the example here:
http://msdn.microsoft.com/en-us/library/hh202956%28v=VS.92%29.aspx
My problem is that when I run the app on my phone, the ViewFinder image is always showing up rotated 90 degrees counter-clockwise. This is the case no matter how the phone is positioned.
Does anyone know how I can orient the ViewFinder correctly?
Yes, the orientation is something you'll need to manage with a Relative Transform:
<!--Camera viewfinder >-->
<Rectangle Grid.Row="1"
x:Name="preview">
<Rectangle.Fill>
<VideoBrush x:Name="previewBrush">
<VideoBrush.RelativeTransform>
<CompositeTransform x:Name="previewTransform"
CenterX=".5"
CenterY=".5" />
</VideoBrush.RelativeTransform>
</VideoBrush>
</Rectangle.Fill>
</Rectangle>
Then you can use the PhotoCamera class to determine how you want to rotate it:
double cameraRotation = theCamera.Orientation;
// Use the orientation to determine how to transform
// the camera preview
previewTransform.Rotation = theCamera.Orientation + 90.0; // Landscape?
HTH
Adding more clarification to the answer: One thing the documentation describes that isn't mentioned here is that the relative transform is adjusted in the OnOrientationChanged event. Another difference is that the relative transform isn't specified in the XAML.
In the docs (How to: Create a Base Camera Application for Windows Phone), the rectangle is filled with the videobrush as follows:
<!--Camera viewfinder >-->
<Rectangle Width="640" Height="480"
HorizontalAlignment="Left"
x:Name="viewfinderContainer">
<Rectangle.Fill>
<VideoBrush x:Name="viewfinderBrush" />
</Rectangle.Fill>
</Rectangle>
Then, in the code-behind, the OnOrientationChanged event rotates the rectangle based on orientation:
// Ensure that the viewfinder is upright in LandscapeRight.
protected override void OnOrientationChanged(OrientationChangedEventArgs e)
{
if (e.Orientation == PageOrientation.LandscapeRight)
{
viewfinderBrush.RelativeTransform =
new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 180 };
}
else
{
viewfinderBrush.RelativeTransform =
new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 0 };
}
base.OnOrientationChanged(e);
}
The code in this topic (which corresponds to the sample) is configured to only use landscape orientation, maybe this is why you're only getting landscape images(?) At the beginning, the following attributes are added to the phone:PhoneApplicationPage element in MainPage.xaml:
SupportedOrientations="Landscape" Orientation="LandscapeLeft"
If you are still getting images orientated incorrectly, sync your images to your PC and see if they're oriented correctly while viewing them there (on your PC). It could be a bug with the Beta that is causing the image to not appear correctly on the device.
Hope that helps. Cheers
You do not need to do that much code, assuming you are in portrait mode, just call:
viewfinderBrush.RelativeTransform
= new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 90 };
But of course, whatever orientation you use for the viewfinder, the resulting image IS still in landscape! Does anybody have an idea how to best fix this?
yes, I deleted the OnOrientationChanged-Eventhandler and just set the transform. In Xaml of course I changed the orientation to portrait.
Now, the viewfinder shows portrait and the page is portrait as well. But the image is saved as thumbnail to the camera roll, so I can see directly on device that the captured image has still landscape orientation.
Would be cool, if someone could verify that this is a Beta bug, or if we have just done some stupid code here ;)
Thanks.

Bind xaml vector images dynamically

I'm looking for a way to bind xaml images dynamically in code.
There are lots of examples online to show how to bind png or xaml images in the window's xaml, or to load png files in code.
But I have found no examples for xaml files with build action=page. XmlReader can't handle them since they are compiled to baml.
LoadComponent(new Uri("...filename.baml") will apparently load the baml but what kind of image class do I load this into? BitmapImage(new Uri("...filename.baml") does not seem to work, probably because it's not a bitmap.
Thanks in advance.
Additionally, if your image is stored in a Xaml vector file in this kind of format:
You can load the individual xaml vector images in the following way (it is probably best to prevent the dictionary being added multiple times, if like me, you are loading it via an OpenFileDialog):
C#:
string fullPathAndFileName = "C:\Image_Name.xaml";
ResourceDictionary dict = new ResourceDictionary();
dict.Source = new Uri(fullPathAndFileName);
Application.Current.Resources.MergedDictionaries.Add(dict);
DrawingImage image = dict[dict.Keys.Cast().ToList()[0]] as DrawingImage;
myImage.Source = image;
Xml:
Image Height="200" Width="200" x:Name="myImage"
After much trial and error and searching, the following article helped me on my way:
Access ResourceDictionary items programmatically
If each Xaml vector image is contained inside a ResourceDictionary with a key (see my 2nd post below for the format)...
If your Xaml vector image files are all stored in your project (build action: page), you can load them in the following way:
//Get the ResourceDictionary using the xaml filename:
ResourceDictionary dict = System.Windows.Application.LoadComponent(new Uri("/yourprojectname;component/youriconfolder/youriconfilename.xaml", System.UriKind.Relative)) as ResourceDictionary;
//Get the xaml as a DrawingImage out the ResourceDictionary
DrawingImage image = dict[dict.Keys.Cast<object>().ToList()[0]] as DrawingImage;
I could return the image and bind it to the viewmodel property, which returns the iconfilename.xaml. Then I use a converter with the above code to lookup the icon and return it as a DrawingImage.
Or you can assign it as the source of an Image (see my 2nd post below).
UPDATE: 2015.10.08 - It seems Carl didn't get around to the "XAML format example" part of his post. The XAML would look something like this:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DrawingImage x:Key="SomeUniqueKey">
<DrawingImage.Drawing>
<DrawingGroup>
...
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</ResourceDictionary>
Then you could do:
DrawingImage image = dict["SomeUniqueKey"] as DrawingImage;
Or, if you prefer using the Image directly,
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Image x:Key="SomeUniqueImage">
<Image.Source>
<DrawingImage>
...
</DrawingImage>
</Image.Source>
</Image>
</ResourceDictionary>
And:
Image someImage = dict["SomeUniqueImage"] as Image;