Images in Windows Phone 8.1 livetiles aren't sharp - c#

I create livetiles with the following code:
// wide 310x150
var tileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileWide310x150PeekImage03);
tileXml.GetElementsByTagName(textElementName).LastOrDefault().InnerText = string.Format(artist + " - " + trackname);
var image = tileXml.GetElementsByTagName(imageElementName).FirstOrDefault();
if (image != null)
{
var src = tileXml.CreateAttribute("src");
if (albumart == String.Empty)
src.Value = "Assets/onemusic_logo_wide.scale-240.png";
else
src.Value = albumart;
image.Attributes.SetNamedItem(src);
}
// square 150x150
var squaredTileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150PeekImageAndText01);
squaredTileXml.GetElementsByTagName(textElementName).FirstOrDefault().InnerText = string.Format(artist + " - " + trackname);
image = squaredTileXml.GetElementsByTagName(imageElementName).LastOrDefault();
if (image != null)
{
var src = squaredTileXml.CreateAttribute("src");
if (albumart == String.Empty)
src.Value = "Assets/onemusic_logo_square.scale-240.png";
else
src.Value = albumart;
image.Attributes.SetNamedItem(src);
}
updater.Update(new TileNotification(tileXml));
updater.Update(new TileNotification(squaredTileXml));
The problem I face is that the images shown on the livetile aren't sharp (in the app they are). I think this is because of the 310x150 pixels size of the template. I looked at the templates, there aren't any higher resolution ones. Is there a way to make the images sharper?

I noticed that providing an image with a resolution of exactly 744x360 pixels solves the problem. So I wrote this function to resize my albumarts (maybe it will come in handy for someone);
private async static Task<string> CropAndSaveImage(string filePath)
{
const string croppedimage = "cropped_albumart.jpg";
// read file
StorageFile file = await StorageFile.GetFileFromPathAsync(filePath);
if (file == null)
return String.Empty;
// create a stream from the file and decode the image
var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
// create a new stream and encoder for the new image
using (InMemoryRandomAccessStream writeStream = new InMemoryRandomAccessStream())
{
// create encoder
BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(writeStream, decoder);
enc.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Linear;
// convert the entire bitmap to a 744px by 744px bitmap
enc.BitmapTransform.ScaledHeight = 744;
enc.BitmapTransform.ScaledWidth = 744;
enc.BitmapTransform.Bounds = new BitmapBounds()
{
Height = 360,
Width = 744,
X = 0,
Y = 192
};
await enc.FlushAsync();
StorageFile albumartfile = await ApplicationData.Current.LocalFolder.CreateFileAsync(croppedimage, CreationCollisionOption.ReplaceExisting);
using (var stream = await albumartfile.OpenAsync(FileAccessMode.ReadWrite))
{
await RandomAccessStream.CopyAndCloseAsync(writeStream.GetInputStreamAt(0), stream.GetOutputStreamAt(0));
}
// return image path
return albumartfile.Path;
}
}

Related

the images turn black during conversion

i converted an image.png to svg using ImageMagick and Potrace.
These images have no background so my converter makes a white background after Process.
Now when I convert this svg to png using PlaywrightSharp-Nuget, I get a black image in the Output(the images turn black).
this problem occurs when only my original png photo at the beginning has no background!
the reason for using PlaywrightSharp is the output has no copyright-sentence on the image.
{
width = 256;
height = 256;
string pngFileNamePath = fileNameSource.Replace(".svg", ".png");
string sourcePathWithoutSourceFileName = pngFileNamePath.Substring(0, pngFileNamePath.LastIndexOf('\\'));
string pngFileName = pngFileNamePath.Replace(sourcePathWithoutSourceFileName + "\\", "");
string pngInTemp = Path.Combine(workingPath, pngFileName);
XDocument sourceXDocumentForSvg = XDocument.Load(fileNameSource);
XNamespace nameSpace = "http://www.w3.org/2000/svg";
var svggElement = sourceXDocumentForSvg.Element(nameSpace + "svg");
svggElement.SetAttributeValue("width", width);
svggElement.SetAttributeValue("height", height);
sourceXDocumentForSvg.Save(fileNameSource);
await PlaywrightSharp.Playwright.InstallAsync();
using var playwright = await PlaywrightSharp.Playwright.CreateAsync();
await using var browser = await playwright.Webkit.LaunchAsync(headless: false);
var page = await browser.NewPageAsync();
await page.SetViewportSizeAsync(width, height);
await page.GoToAsync(Path.GetFullPath(fileNameSource));
var item = await page.QuerySelectorAsync("svg");
await item.ScreenshotAsync(pngFileNamePath, omitBackground: true);
File.Move(pngFileNamePath, pngInTemp);
}```

How can set image according to format in SimplePdfViewerControl in UWP

When I tried to view image in PdfViewer with Letter Format then Image is bluring. while when I tried viewing without defined format then picture is clear.
My Code
private async void Load(PdfDocument pdfDoc)
{
try
{
PdfPages.Clear();
for (uint i = 0; i < pdfDoc.PageCount; i++)
{
BitmapImage image = new BitmapImage();
var page = pdfDoc.GetPage(i);
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
//PdfPageRenderOptions pdfPageRenderOptions = new PdfPageRenderOptions();
{
await page.RenderToStreamAsync(stream);
await image.SetSourceAsync(stream);
}
PdfPages.Add(image);
}
}
This Code Belong to Format set
StorageFile ImageFile;
var storageFolder = await KnownFolders.GetFolderForUserAsync(null, KnownFolderId.PicturesLibrary);
StorageFolder projectFolder = await storageFolder.CreateFolderAsync(imageLocation, CreationCollisionOption.OpenIfExists);
StorageFile file = await projectFolder.GetFileAsync(item);
if (file == null) return;
var Stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
IRandomAccessStream stream = await file.OpenReadAsync();
Stream imageStream = stream.AsStreamForRead();
BitmapImage sourceImage = new BitmapImage();
PdfBitmap image = new PdfBitmap(imageStream);
PdfSection section1 = doc.Sections.Add();
section1.PageSettings.Size = PdfPageSize.Letter;
page = section1.Pages.Add();
PdfGraphics graphics = page.Graphics;
//Draw the image
if (fileType == Constants.PrescriptionType.Prescription.GetHashCode())
graphics.DrawImage(image, 0, 0, page.Graphics.ClientSize.Width, page.Graphics.ClientSize.Height);
else
graphics.DrawImage(image, 0, 0, page.Graphics.ClientSize.Width, page.Graphics.ClientSize.Height);
Thank You

Convert imageSource coming from Xam.Plugin.Media 5.0.1 to byte array in Xamarinforms?

if (!CrossMedia.Current.IsPickPhotoSupported)
{
await Application.Current.MainPage.DisplayAlert("Photos Not Supported", ":( Permission not granted to photos.", "OK");
return;
}
var file = await Plugin.Media.CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium,
});
if (file == null)
return;
var tmpSrc = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
ImageSource toBeConverted = tmpSrc;
I want the variable toBeConverted to be converted into Byte[] so
that I can send it to my webapi ...
ImageSource is a way to provide a source image for Xamarin.Forms.Image to show some content. If you're already showing something on the screen your Image view was populated with data that came from elsewhere, such as a file or resource or stored in an array in memory... or however else you got that in the first place. Instead of trying to get that data back from ImageSource you can keep a reference to it and upload it as needed.
So you could get the byte array from the file after you pick the photo.
var file = await Plugin.Media.CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium,
});
if (file == null)
return;
var bytes = File.ReadAllBytes(file.Path); // you could get the byte[] here from the file path.
This code also worked for me ...
private async void Capture()
{
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await Application.Current.MainPage.DisplayAlert("No Camera", ":( No camera available.", "OK");
return;
}
var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
Directory = "Test",
SaveToAlbum = true,
CompressionQuality = 75,
CustomPhotoSize = 50,
PhotoSize = PhotoSize.Medium,
DefaultCamera = CameraDevice.Front
});
if (file == null)
return;
var stream = file.GetStream();
if (stream != null)
{
var StreamByte = ReadAllBytes(stream);
var NewStream = new MemoryStream(StreamByte);
// stream = mystream;
Device.BeginInvokeOnMainThread(() => {
ImageSource = ImageSource.FromStream(() => NewStream);
});
student.ProfilePicture = StreamByte;
}
}
public byte[] ReadAllBytes(Stream instream)
{
if (instream is MemoryStream)
return ((MemoryStream)instream).ToArray();
using (var memoryStream = new MemoryStream())
{
instream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}

C# How to reduce the size of the stream (image)

All I have is the Stream of the file (the file is image/jpeg type). I want to reduce the quality of the image (example: original 2MB -> 200KB).
var contentStream = ImageSource.FromStream(() => { return _MediaFile.GetStream(); });
newImg.Source = contentStream;
_ReportModel.Add(new ReportPicture()
{
Id = layout.Id,
Path = _MediaFile.Path,
Content = _MediaFile.GetStream()
});
Before I upload the _ReportModel to my server using REST API, I want to reduce the size of the Content which contains the stream of the read image (type jpeg).
I need something like:
private Stream ReduceStreamSize(Stream oldStream)
{
var reducedStream = //doSomething(oldStream);
return reducedStream;
}
How can I do this?
Update
I have tried this:
public Stream CompressImage(string imagePath)
{
try
{
// BitmapFactory options to downsize the image
BitmapFactory.Options o = new BitmapFactory.Options();
o.InJustDecodeBounds = true;
o.InSampleSize = 6;
// factor of downsizing the image
FileStream inputStream = new FileStream(imagePath, FileMode.Open);
//Bitmap selectedBitmap = null;
BitmapFactory.DecodeStream(inputStream, null, o);
inputStream.Close();
// The new size we want to scale to
int REQUIRED_SIZE = 75;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while (o.OutWidth / scale / 2 >= REQUIRED_SIZE &&
o.OutHeight / scale / 2 >= REQUIRED_SIZE)
{
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.InSampleSize = scale;
inputStream = new FileStream(imagePath, FileMode.Open);
Bitmap selectedBitmap = BitmapFactory.DecodeStream(inputStream, null, o2);
inputStream.Close();
FileStream outputStream = new FileStream(imagePath, FileMode.Open);
selectedBitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, outputStream);
return outputStream;
}
catch (Exception e)
{
return null;
}
}
But the image is not showing. There must be an error while compressing it.

UWP - scaled image is damaged

I have a problem to place an image with down-scale. Image is rasterized and I don't know find way to place it correctly.
Is it possible to place picture without losing quality ?
Code:
public async Task<BitmapImage> BitmapTransform(string filePath, uint width)
{
StorageFile file = await StorageFile.GetFileFromPathAsync(filePath);
if (file == null)
return null;
// create a stream from the file and decode the image
var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
// create a new stream and encoder for the new image
InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(ras, decoder);
double ration =
enc.BitmapTransform.ScaledWidth = width;
enc.BitmapTransform.ScaledHeight = (uint)(((double)decoder.PixelHeight / (double)decoder.PixelWidth) * (double)width);
// write out to the stream
try
{
await enc.FlushAsync();
}
catch (Exception ex)
{
string s = ex.ToString();
}
// render the stream to the screen
BitmapImage bImg = new BitmapImage();
bImg.SetSource(ras);
return bImg;
}
You can choose the way of resizing - Nearest Neighbor, Linear, Cubic, Fant - by BitmapTransform.InterporationMode property.
Have you tried it?
https://msdn.microsoft.com/en-us/library/windows/apps/windows.graphics.imaging.bitmaptransform.interpolationmode
double ration =
enc.BitmapTransform.ScaledWidth = width;
enc.BitmapTransform.ScaledHeight = (uint)(((double)decoder.PixelHeight / (double)decoder.PixelWidth) * (double)width);
enc.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Cubic; // <----- Set the Interporation mode here
But the quality of result is vary. It's depend on the original image.

Categories