I am having trouble setting the lock screen to an image, but I think it is not a problem with a Uri but rather with the image itself.
When I try to set the image to a downloaded image that has approximately the right size for the lockscreen it works, also when an image is not too big. But when I try to set the lockscreen image to a photo from the camera (Nokia Lumia 920) it gives me this Argument Exception.
My Code:
// From the StorageHelper class:
public async Task<bool> SavePhotoAsync(Photo photo, WriteableBitmap source, int height, int width)
{
return await Task.Run(() =>
{
try
{
lock (StorageLock)
{
ObservableCollection<Photo> observableCollection = photo.PhotoAlbum.Photos as ObservableCollection<Photo>;
if (observableCollection == null)
{
return false;
}
if (!IsolatedStorageFile.GetUserStoreForApplication().DirectoryExists(photo.PhotoAlbum.Name))
{
IsolatedStorageFile.GetUserStoreForApplication().CreateDirectory(photo.PhotoAlbum.Name);
}
string fileName = photo.PhotoAlbum.Name + "/" + observableCollection.IndexOf(photo).ToString(CultureInfo.InvariantCulture);
if (IsolatedStorageFile.GetUserStoreForApplication().FileExists(fileName))
{
IsolatedStorageFile.GetUserStoreForApplication().DeleteFile(fileName);
}
IsolatedStorageFileStream fileStream =
IsolatedStorageFile.GetUserStoreForApplication().CreateFile(fileName);
int targetWidth = 0;
int targetHeight = 0;
if (source.PixelWidth < width || source.PixelHeight < height)
{
targetWidth = source.PixelWidth;
targetHeight = source.PixelHeight;
}
else
{
if (source.PixelWidth > source.PixelHeight)
{
double percentage = ((double)height)/((double) source.PixelHeight);
targetHeight = height;
targetWidth = (int) (source.PixelWidth * percentage);
}
else
{
double percentage = ((double)width) / ((double)source.PixelWidth);
targetWidth = width;
targetHeight = (int)(source.PixelHeight * percentage);
}
}
source.SaveJpeg(fileStream, targetWidth, targetHeight, 0, 100);
fileStream.Close();
return true;
}
}
catch (Exception e)
{
return false;
}
});
}
// End of StorageHelper
// From my LockscreenManager class:
public static async void SetLockScreenImages()
{
LockScreenRequestResult result = await LockScreenManager.RequestAccessAsync();
if (result == LockScreenRequestResult.Granted)
{
Uri uri = null;
try
{
uri = LockScreen.GetImageUri();
}
catch (Exception)
{
}
List<Uri> uriList = await BuildUriList();
if (uriList.Count == 0)
{
return;
}
int index = 0;
if (uri != null && uriList.Any(uriEntry => uri.ToString() == uriEntry.ToString()))
{
index = (uriList.IndexOf(uri) + 1) % uriList.Count;
}
if (InterfaceProvider.GetIStorageService().FileExists(uriList[index]))
{
try
{
LockScreen.SetImageUri(uriList[index]);
}
catch (Exception)
{
}
}
}
}
// End of Lockscreenmanager class
You can ignore my try to shrink down the image, it didn't help (but the images are still saved correctly). What could I do?
Related
I'm Fairly new to WPF and MVVM in general, I'm trying to follow this tutorial to create a stacked bar chart in telerik/WPF C#:
https://docs.telerik.com/devtools/winforms/knowledge-base/chartview-summary-labels-stacked-bars
But I'm, unsure where to implement the "Custom Renderer and Labels" Code, Can't seem to have it work. Should I declare a seperate class or something? A rough step by step guide is all i need, thanks in advance
this is the example code (I'm not sure where to put it)
public class CustomCartesianRenderer : CartesianRenderer
{
public CustomCartesianRenderer(CartesianArea area)
: base(area)
{ }
protected override void InitializeSeriesLabels()
{
base.InitializeSeriesLabels();
IDictionary<object, List<double?>> summaryValues = new Dictionary<object, List<double?>>();
for (int i = 0; i < this.Area.Series.Count; i++)
{
BarSeries barSeries = this.Area.Series[i] as BarSeries;
if (barSeries == null)
{
continue;
}
for (int j = 0; j < barSeries.DataPoints.Count; j++)
{
CategoricalDataPoint dp = (CategoricalDataPoint)barSeries.DataPoints[j];
if (!summaryValues.ContainsKey(dp.Category))
{
summaryValues.Add(dp.Category, new List<double?>() { dp.Value });
}
else
{
summaryValues[dp.Category].Add(dp.Value);
}
}
}
string lastSeriesName = this.Area.Series[this.Area.Series.Count - 1].Name;
for (int i = 0; i < this.DrawParts.Count; i++)
{
BarLabelElementDrawPart labelPart = this.DrawParts[i] as BarLabelElementDrawPart;
if (labelPart != null && labelPart.Element.Name == lastSeriesName)
{
CustomBarLabelElementDrawPart customLabelPart = new CustomBarLabelElementDrawPart((BarSeries)labelPart.Element, this);
customLabelPart.SummaryValues = summaryValues;
this.DrawParts[i] = customLabelPart;
}
}
}
}
public class CustomBarLabelElementDrawPart : BarLabelElementDrawPart
{
private IDictionary<object, List<double?>> summaryValues;
public CustomBarLabelElementDrawPart(BarSeries series, IChartRenderer renderer)
: base(series, renderer)
{ }
public IDictionary<object, List<double?>> SummaryValues
{
get
{
return this.summaryValues;
}
set
{
this.summaryValues = value;
}
}
public override void Draw()
{
Graphics graphics = this.Renderer.Surface as Graphics;
RadGdiGraphics radGraphics = new RadGdiGraphics(graphics);
foreach (DataPointElement dataPointElement in this.Element.Children)
{
CategoricalDataPoint categoricalDataPoint = dataPointElement.DataPoint as CategoricalDataPoint;
if (!this.summaryValues.ContainsKey(categoricalDataPoint.Category))
{
continue;
}
double? sum = this.summaryValues[categoricalDataPoint.Category].Sum();
string summaryText = string.Format("Sum: {0}", sum);
RadRect slot = categoricalDataPoint.LayoutSlot;
RectangleF barBounds = new RectangleF((float)(this.OffsetX + slot.X), (float)(this.OffsetY + slot.Y), (float)slot.Width, (float)slot.Height);
float realHeight = barBounds.Height * dataPointElement.HeightAspectRatio;
barBounds.Y += barBounds.Height - realHeight;
barBounds.Height = realHeight;
barBounds = this.AdjustBarDataPointBounds(dataPointElement, barBounds);
barBounds.Width = Math.Max(barBounds.Width, 1f);
object state = radGraphics.SaveState();
int horizontalTranslate = (int)(barBounds.X + barBounds.Width / 2);
int verticalTranslate = (int)(barBounds.Y + barBounds.Height / 2);
float angle = (float)this.Element.LabelRotationAngle % 360f;
if (angle != 0)
{
radGraphics.TranslateTransform(horizontalTranslate, verticalTranslate);
radGraphics.RotateTransform(angle);
radGraphics.TranslateTransform(-horizontalTranslate, -verticalTranslate);
}
Size desiredSize = TextRenderer.MeasureText(summaryText, dataPointElement.Font);
FillPrimitiveImpl fill = new FillPrimitiveImpl(dataPointElement, null);
fill.PaintFill(radGraphics, 0, Size.Empty, barBounds);
BorderPrimitiveImpl border = new BorderPrimitiveImpl(dataPointElement, null);
border.PaintBorder(radGraphics, 0, Size.Empty, barBounds);
using (Brush brush = new SolidBrush(dataPointElement.ForeColor))
{
RectangleF drawRectangle = new RectangleF();
drawRectangle.X = barBounds.X + dataPointElement.Padding.Left + (barBounds.Width - desiredSize.Width) /2;
drawRectangle.Y = barBounds.Y + dataPointElement.Padding.Top - desiredSize.Height;
drawRectangle.Width = barBounds.Width - dataPointElement.Padding.Right;
drawRectangle.Height = barBounds.Height - dataPointElement.Padding.Bottom;
StringFormat format = new StringFormat();
graphics.DrawString(summaryText, dataPointElement.Font, brush, drawRectangle, format);
}
if (angle != 0)
{
radGraphics.ResetTransform();
}
radGraphics.RestoreState(state);
}
base.Draw();
}
private RectangleF AdjustBarDataPointBounds(DataPointElement point, RectangleF bounds)
{
RectangleF barBounds = bounds;
if (point.BorderBoxStyle == BorderBoxStyle.SingleBorder || point.BorderBoxStyle == BorderBoxStyle.OuterInnerBorders)
{
barBounds.X += point.BorderWidth - (int)((point.BorderWidth - 1f) / 2f);
barBounds.Width -= point.BorderWidth;
barBounds.Y += point.BorderWidth - (int)((point.BorderWidth - 1f) / 2f);
barBounds.Height -= point.BorderWidth;
}
else if (point.BorderBoxStyle == BorderBoxStyle.FourBorders)
{
barBounds.Y += 1;
barBounds.Height -= 1;
barBounds.X += 1;
barBounds.Width -= 1;
}
if (((CartesianRenderer)this.Renderer).Area.Orientation == System.Windows.Forms.Orientation.Horizontal)
{
barBounds.X--;
}
return barBounds;
}
}
We have started a project for printing, however we are completely stuck when it comes to telling the printer what paper size is selected.
Everytime we select the paper size and hit print, the printer preview is showing A4 everytime and not our selected size although if we open the print preferences the correct size is selected.
namespace CPrint
{
/// <summary>
/// Логика взаимодействия для ucPrint.xaml
/// </summary>
public partial class ucPrint : UserControl
{
bool SystemChange = false;
double? PaperHeight = null;
double? PaperWidth = null;
public ucPrint()
{
InitializeComponent();
App.Localization.AddControls(this, new string[]
{
"cHeader", "lPrinter", "lCopies","lLayout", "bPrintSettings","lColorManagement","lPrinterProfile", "lPositionSize", "cCenter", "lTop", "lLeft"
});
}
public static BitmapSource ConvertColorProfile(BitmapSource bitmapSource, ColorContext sourceProfile, ColorContext destinationProfile)
{
var bitmapConverted = new ColorConvertedBitmap();
bitmapConverted.BeginInit();
bitmapConverted.Source = bitmapSource;
//bitmapConverted.SourceColorContext = new ColorContext(PixelFormats.Pbgra32);// bitmapSourceFrame.ColorContexts == null ? sourceProfile : bitmapSourceFrame.ColorContexts[0];
bitmapConverted.SourceColorContext = sourceProfile;
bitmapConverted.DestinationColorContext = destinationProfile;
bitmapConverted.DestinationFormat = PixelFormats.Bgra32;
bitmapConverted.EndInit();
return bitmapConverted;
}
private void BPrint_Click(object sender, RoutedEventArgs e)
{
if (cPrinter.SelectedItem == null) { MessageBox.Show("Printer not set"); return; }
if (cPaperSize.SelectedItem == null) { MessageBox.Show("Paper size not set"); return; }
double marging = 30;
if (App.CurrentTemplateControl != null)
{
var img = App.CurrentTemplateControl.GetImage(true);
if (img == null) return;
var image = new Image() { Source = img };
if (cColorProfile != null && cColorProfile.SelectedItem != null && cColorProfile.SelectedIndex > 0)
{
Uri sourceProfileUri = new Uri((cColorProfile.SelectedItem as FileInfo).FullName);
image.Source = ConvertColorProfile(image.Source as BitmapSource, new ColorContext(PixelFormats.Pbgra32), new ColorContext(sourceProfileUri));
}
if (cMirror.IsChecked == true)
{
var transformGroup = new TransformGroup();
transformGroup.Children.Add(new ScaleTransform(-1, 1, img.Width / 2, img.Height / 2));
image.RenderTransform = transformGroup;
}
PrintDialog printDialog2 = new PrintDialog();
Size size = (Size)(cPaperSize.SelectedItem as ComboBoxItem).DataContext;
printDialog2.PrintQueue = new PrintQueue(new PrintServer(), cPrinter.Text);
//if (printDialog2.ShowDialog() == true)
//{
//Size size = new Size(printDialog2.PrintableAreaWidth, printDialog2.PrintableAreaHeight);
printDialog2.PrintTicket = new PrintTicket()
{
PageMediaSize = new PageMediaSize(size.Width, size.Height)
};
//printDialog2.PrintTicket
Canvas canvas = new Canvas()
{
//Height = PrintContext.ToPx(size.Height),
//Width = PrintContext.ToPx(size.Width),
Height = size.Height,
Width = size.Width,
Background = Brushes.White
};
canvas.Children.Add(image);
double scaleW = (size.Width - marging * 2) / img.Width;
double scaleH = (size.Height - marging * 2) / img.Height;
if (scaleW < 1 || scaleH < 1)
{
Canvas.SetLeft(image, marging);
Canvas.SetTop(image, marging);
double scale = scaleW > scaleH ? scaleH : scaleW;
var transformGroup = new TransformGroup();
transformGroup.Children.Add(new ScaleTransform(scale, scale, 0, 0));
image.RenderTransform = transformGroup;
}
else if (cCenter.IsChecked == true)
{
Canvas.SetLeft(image, size.Width / 2 - img.Width / 2);
Canvas.SetTop(image, size.Height / 2 - img.Height / 2);
}
else
{
Canvas.SetLeft(image, marging);
Canvas.SetTop(image, marging);
}
printDialog2.PrintVisual(canvas, "Print");
//}
}
return;
}
private void CPrinter_DropDownOpened(object sender, EventArgs e)
{
SystemChange = true;
var lastPrinterName = cPrinter.Text;
cPrinter.Items.Clear();
int index = -1;
cPrinter.SelectedIndex = index;
foreach (string strPrinter in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
{
index++;
cPrinter.Items.Add(strPrinter);
if (strPrinter == lastPrinterName)
cPrinter.SelectedIndex = index;
}
SystemChange = false;
}
private void CPrinter_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0 && SystemChange == false)
{
var printer = new System.Drawing.Printing.PrinterSettings();
printer.PrinterName = e.AddedItems[0].ToString();
var lastPaperName = cPaperSize.Text;
cPaperSize.Items.Clear();
int index = -1;
cPaperSize.SelectedIndex = index;
foreach (System.Drawing.Printing.PaperSize paper in printer.PaperSizes)
{
index++;
cPaperSize.Items.Add(new ComboBoxItem() { Content = paper.PaperName, DataContext = new Size(paper.Width, paper.Height) });
if (paper.PaperName == lastPaperName)
cPaperSize.SelectedIndex = index;
}
Properties.Settings.Default.DefaultDirectPrinter = printer.PrinterName;
Properties.Settings.Default.Save();
}
}
private void CPaperSize_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
Properties.Settings.Default.DefaultDirectPaper = ((ComboBoxItem)e.AddedItems[0]).Content.ToString();
Properties.Settings.Default.Save();
}
}
public void UpdateControls()
{
SystemChange = true;
if (!String.IsNullOrWhiteSpace(Properties.Settings.Default.DefaultDirectPrinter))
{
SystemChange = true;
var lastPrinterName = cPrinter.Text;
cPrinter.Items.Clear();
int index = -1;
cPrinter.SelectedIndex = index;
foreach (string strPrinter in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
{
index++;
cPrinter.Items.Add(strPrinter);
if (strPrinter == Properties.Settings.Default.DefaultDirectPrinter)
cPrinter.SelectedIndex = index;
}
SystemChange = false;
if (!String.IsNullOrWhiteSpace(Properties.Settings.Default.DefaultDirectPaper))
{
var printer = new System.Drawing.Printing.PrinterSettings();
printer.PrinterName = Properties.Settings.Default.DefaultDirectPrinter;
string lastPaperName = Properties.Settings.Default.DefaultDirectPaper;
cPaperSize.Items.Clear();
int indexP = -1;
cPaperSize.SelectedIndex = indexP;
foreach (System.Drawing.Printing.PaperSize paper in printer.PaperSizes)
{
indexP++;
cPaperSize.Items.Add(new ComboBoxItem() { Content = paper.PaperName, DataContext = new Size(paper.Width, paper.Height) });
if (paper.PaperName == lastPaperName)
cPaperSize.SelectedIndex = indexP;
}
}
}
if (!String.IsNullOrWhiteSpace(Properties.Settings.Default.DefaultDirectColorProfile))
{
var lastValue = Properties.Settings.Default.DefaultDirectColorProfile;
cColorProfile.Items.Clear();
int index = -1;
cColorProfile.SelectedIndex = index;
cColorProfile.Items.Add("");
index++;
foreach (var file in App.Icc.items)
{
index++;
cColorProfile.Items.Add(file);
if (file.FullName == lastValue)
cColorProfile.SelectedIndex = index;
}
}
SystemChange = false;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
}
private void CColorProfile_DropDownOpened(object sender, EventArgs e)
{
var lastValue = cColorProfile.Text;
cColorProfile.Items.Clear();
int index = -1;
cColorProfile.SelectedIndex = index;
cColorProfile.Items.Add("");
index++;
foreach (var file in App.Icc.items)
{
index++;
cColorProfile.Items.Add(file);
if (file.Name == lastValue)
cColorProfile.SelectedIndex = index;
}
}
private void CColorProfile_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!SystemChange)
{
Properties.Settings.Default.DefaultDirectColorProfile = (cColorProfile.SelectedItem as FileInfo)?.FullName;
Properties.Settings.Default.Save();
}
}
}
}
I expect if we select A5, it tells the print driver to print A5,
If we select a custom "user defined" paper size, it tells the printer which size is selected. And not fixing this at A4 everytime
We cant seem to set the paper size outside the print dialog.
I believe; following this and this MSDN article; you are going to want to do something along the lines of:
System.Drawing.Printing.PaperSize paperSize = new System.Drawing.Printing.PaperSize("custom", width, height);
PrintDocument printDoc = new PrintDocument();
printDoc.DefaultPageSettings.PaperSize = paperSize;
I have walk through your code,
I think some event raise by front end (XAML) on specific use cases that is the overriding the actual value in "Properties.Settings.Default."
It would be better to resolve if you provide a XAML code for this issue.
I can look into it and will give you better solution.
You can share me code here is my skype : shsakariya
I'm working on a software in C# used to manipulate images. I have a lot of images (more than 11000) and when I execute my program after a few minutes, I have an "OutOfMemoryException"
There is my code :
private void GenerateImages()
{
try
{
Parallel.ForEach(listImagesStart, startImg =>
{
bool docontinue = true;
try
{
startImg.LoadImage(_baseFileResults);
}
catch
{
docontinue = false;
}
if (docontinue)
{
//Save image as file
startImg.Save();
// Do rotate
MyImg lastRotate = baseImg;
MyImg imgtmp;
String[] tabRotate = new String[3] { "_90", "_180", "_270"};
foreach (String rotate in tabRotate)
{
imgtmp = new GenImg(baseImg.FileName + rotate + baseImg.FileExtension);
imgtmp.LoadImage(lastRotate);
imgtmp.Rotate90();
imgtmp.Save();
lastRotate = imgtmp;
}
startImg.Dispose();
imgtmp.Dispose();
}
});
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
#if DEBUG
MessageBox.Show(e.StackTrace, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
#endif
}
}
And MyImg :
class myImg
{
public Byte[] Matrix;
public int Height;
public int Width;
public void LoadImage(String filePath)
{
// create new Matrix/Heigth/Width from file
}
public void LoadImage(myImg img)
{
Matrix = new Byte[img.Matrix.Length];
Array.Copy(img.Matrix, Matrix, img.Matrix.Length);
Height = img.Height;
Width = img.Width;
}
public void Rotate90()
{
// Save before
int tmpWidth = Height;
int tmpHeight = Width;
Byte[] tmpMatrix = new Byte[Matrix.Length];
for (int r = 0; r < tmpHeight; r++)
{
for (int c = 0; c < tmpWidth; c++)
{
int prevR = Height - c - 1;
int prevC = r;
tmpMatrix[c + r * tmpWidth] = Matrix[prevC + prevR * Width];
}
}
// Copy new image
Array.Copy(tmpMatrix, Matrix, Matrix.Length);
Width = tmpWidth;
Height = tmpHeight;
}
public void Dispose()
{
SavePath = null;
Matrix = null;
Points = null;
Width = 0;
Height = 0;
GC.Collect();
}
}
The SystemOutOfMemoryException occurs at instructionnew Byte[Length]. I think it's I create too many array but I don't know what to do.
The main issue is that listImagesStart keeps reference of each startImg item. This will keep GC from freeing memory allocated by myImg.LoadImage (with the array Matrix).
A quick solution : you can set Matrix to null to recycle the memory.
public void UnLoadImage()
{
Matrix = null ; // this will allow GC to recycle memory used by Matrix
}
then (I removed the useless docontinue variable) :
try
{
startImg.LoadImage(_baseFileResults);
//Save image as file
startImg.Save();
// Do rotate
MyImg lastRotate = baseImg;
MyImg imgtmp;
String[] tabRotate = new String[3] { "_90", "_180", "_270"};
foreach (String rotate in tabRotate)
{
imgtmp = new GenImg(baseImg.FileName + rotate + baseImg.FileExtension);
imgtmp.LoadImage(lastRotate);
imgtmp.Rotate90();
imgtmp.Save();
lastRotate = imgtmp;
}
startImg.Dispose();
imgtmp.Dispose();
}
catch
{
}
finally
{
startImg.Unload(); // Here is the trick
}
I have a clearly memory leak problem and I need some help/advices to solve it.
My scenario has a simple ListView that displays image and title. This image is a bitmap Image downloaded from server.
After scrolling up and down so FAST this ListView crashes my app, and if i inspect the console i have a OOM Exception like that:
[art] Clamp target GC heap from 111MB to 96MB
[art] Alloc concurrent mark sweep GC freed 3(96B) AllocSpace objects, 0(0B) LOS objects, 0% free, 95MB/96MB, paused 1.187ms total 38.840ms
To avoid that OOM i implemented a LRUCache and DiskCache for store downloaded bitmaps into device, and get this files instead download images again.
This is my ListView Adapter:
public class LazyLoadAdapter : BaseAdapter
{
Activity _activity;
List _products;
BitmapCache cache;
ImageView _imgView;
Dictionary<string, Task> pendingFetch = new Dictionary<string, Task> ();
Bitmap NoMapPicture;
public LazyLoadAdapter(Activity activity, List<CouponExchange> products)
{
_activity = activity;
_products = products;
NoMapPicture = PrepareNoMapPicture (Resource.Drawable.default_coupon);
this.cache = BitmapCache.CreateCache (activity, "MapCache");
}
public override int Count
{
get { return _products.Count; }
}
public override Java.Lang.Object GetItem(int position)
{
return position;
}
public override long GetItemId(int position)
{
return position;
}
public override Android.Views.View GetView(int position, Android.Views.View convertView, Android.Views.ViewGroup parent)
{
if (convertView == null)
{
convertView = _activity.LayoutInflater.Inflate(Resource.Layout.ShopItemList, parent, false);
}
CouponExchange product = _products[position];
TextView txtProductName = convertView.FindViewById<TextView>(Resource.Id.textView24);
txtProductName.Text = product.CouponTitle;
TextView txtProductCost = convertView.FindViewById<TextView>(Resource.Id.textView24b);
txtProductCost.Text = product.Cost.ToString();
_imgView = convertView.FindViewById<ImageView>(Resource.Id.imgProduct);
GetPersonPicture (product.CouponImageUrl);
return convertView;
}
Bitmap DownloadoCacher (string url)
{
Bitmap map = null;
using(map){
map = cache.TryGet2 (url);
if (map!=null)
return map;
byte[] bytes;
using (var wc = new WebClient ()) {
bytes = wc.DownloadData (url);
};
if (bytes != null && bytes.Length > 0) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.InJustDecodeBounds = true;
map = DecodeSampledBitmapFromResource (bytes, 400, 200);
} else {
return map;
}
cache.AddOrUpdate (url, map, TimeSpan.FromDays (1));
return map;
};
}
public static Bitmap DecodeSampledBitmapFromResource(byte[] bytes,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
BitmapFactory.Options options = new BitmapFactory.Options();
options.InJustDecodeBounds = true;
BitmapFactory.DecodeByteArray(bytes, 0, bytes.Length, options);
// Calculate inSampleSize
options.InSampleSize = CalculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.InJustDecodeBounds = false;
return BitmapFactory.DecodeByteArray(bytes, 0, bytes.Length, options);
}
public static int CalculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
int height = options.OutHeight;
int width = options.OutWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
int halfHeight = height / 2;
int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
Bitmap PrepareNoMapPicture (int baseImage)
{
return BitmapFactory.DecodeResource (_activity.Resources, baseImage);
}
Bitmap GetPersonPicture (string url){
if (_imgView == null)
return null;
Bitmap map = null;
using (map) {
map = cache.TryGet2 (url);
if (map!=null) {
_imgView.SetImageBitmap (map);
} else {
_imgView.SetImageBitmap (NoMapPicture);
Action doMapSetting = () => {
_activity.RunOnUiThread (() => {
if (map == null){
map = cache.TryGet2 (url);
}
_imgView.SetImageBitmap (map);
});
};
if (pendingFetch.ContainsKey (url))
pendingFetch [url].ContinueWith (t => doMapSetting (), TaskContinuationOptions.ExecuteSynchronously);
else
pendingFetch[url] = SerialScheduler.Factory.StartNew (() => {
map = DownloadoCacher (url);
doMapSetting ();
});
}
return map;
};
}
Once images are downloaded, my cache gets images from device file.
After scroll up and down so fast, cacheDisk try get images from files and throws OOM Exception:
try {
bmp = Android.Graphics.BitmapFactory.DecodeFile (Path.Combine (basePath, key));
} catch (Exception e) {
var err = e.Message;
return null;
}
All replies would be appreciate. Thanks you
I use this Picasso Binding library for Xamarin :
https://github.com/jacksierkstra/Picasso
This powerful image downloading and caching library allows you to simplify your Image management.
Official documentation :
http://square.github.io/picasso/
Hope this helps
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Smooth text animation (Marquee) using WPF
I am just wondering if there is some best coding approach to scroll text and images horizontally in WPF?
Basically I used some code to do it like
private void PopulateCanvas()
{
canvas1.Width = RootGrid.ActualWidth;
canvas1.Height = RootGrid.ActualHeight;
foreach (var item in PluginContentItems)
{
if (IsImage(item.IPluginContentItemElements))
{
string imageName = GetImageName(item.IPluginContentItemElements);
if (IsGifImage(item.IPluginContentItemElements))
AddGIFImage(imageName);
else
AddImage(imageName);
}
else // Text
{
string text = GetText(item.IPluginContentItemElements);
SolidColorBrush brush = GetFontColor(item.IPluginContentItemElements);
AddTextBlock(text, brush);
}
}
canvas1.Dispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate(Object state)
{
var node = textBlocks.First;
while (node != null)
{
if (node.Previous != null)
{
if (node.Previous.Value.GetType().FullName.Contains("TextBlock"))
Canvas.SetLeft(node.Value, Canvas.GetLeft((TextBlock)node.Previous.Value) + ((TextBlock)node.Previous.Value).ActualWidth); // + gap
else if (node.Previous.Value.GetType().FullName.Contains("GifImage"))
Canvas.SetLeft(node.Value, Canvas.GetLeft((GifImage)node.Previous.Value) + ((GifImage)node.Previous.Value).ActualWidth); // + gap
else if (node.Previous.Value.GetType().FullName.Contains("Controls.Image"))
Canvas.SetLeft(node.Value, Canvas.GetLeft((Image)node.Previous.Value) + ((Image)node.Previous.Value).ActualWidth); // + gap
}
else
{
if (node.Value.GetType().FullName.Contains("TextBlock"))
Canvas.SetLeft((TextBlock)node.Value, canvas1.Width); // + gap
if (node.Value.GetType().FullName.Contains("Image"))
Canvas.SetLeft((Image)node.Value, canvas1.Width); // + gap
if (node.Value.GetType().FullName.Contains("GifImage"))
Canvas.SetLeft((GifImage)node.Value, canvas1.Width); // + gap
}
node = node.Next;
}
return null;
}), null);
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
canvas1.Dispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate(Object state)
{
var node = textBlocks.First;
var lastNode = textBlocks.Last;
while (node != null)
{
double newLeft = Canvas.GetLeft(node.Value) - move_amount;
double w1 = 0;
if (node.Value is TextBlock)
w1 = ((TextBlock)node.Value).ActualWidth;
if (node.Value is Image)
w1 = ((Image)node.Value).ActualWidth;
if (node.Value is GifImage)
w1 = ((GifImage)node.Value).ActualWidth;
if (newLeft < (0 - w1)) // + gap
{
textBlocks.Remove(node);
var lastNodeLeftPos = Canvas.GetLeft(lastNode.Value);
textBlocks.AddLast(node);
if (lastNode.Value.GetType().FullName.Contains("TextBlock"))
{
// + gap
if ((lastNodeLeftPos + ((TextBlock)lastNode.Value).ActualWidth) > canvas1.Width) // Last element is offscreen
newLeft = lastNodeLeftPos + ((TextBlock)lastNode.Value).ActualWidth; // + gap
else
newLeft = canvas1.Width; // +gap;
}
else if (lastNode.Value.GetType().FullName.Contains("GifImage"))
{ // + gap
if ((lastNodeLeftPos + ((GifImage)lastNode.Value).ActualWidth) > canvas1.Width) // Last element is offscreen
newLeft = lastNodeLeftPos + ((GifImage)lastNode.Value).ActualWidth; // + gap
else
newLeft = canvas1.Width; // + gap
}
else if (lastNode.Value.GetType().FullName.Contains("Controls.Image"))
{ // + gap
if ((lastNodeLeftPos + ((Image)lastNode.Value).ActualWidth) > canvas1.Width) // Last element is offscreen
newLeft = lastNodeLeftPos + ((Image)lastNode.Value).ActualWidth; // + gap
else
newLeft = canvas1.Width; // + gap
}
}
Canvas.SetLeft(node.Value, newLeft);
node = node == lastNode ? null : node.Next;
}
return null;
}), null);
}
private void AddGIFImage(string file)
{
try
{
string pathToImage = System.IO.Path.Combine(Settings.ContentFolderPath, file);
Uri u = new Uri(pathToImage);
GifImage gif = new GifImage(u);
gif.Height = canvas1.Height; // canvas1.Height / koeffImage;
canvas1.Children.Add(gif);
Canvas.SetTop(gif, 0);
Canvas.SetLeft(gif, -999);
textBlocks.AddLast(gif);
}
catch (Exception ex)
{
HasError = true;
ErrorMessage = ex.Message;
}
}
private void AddImage(string file)
{
try
{
string pathToImage = System.IO.Path.Combine(Settings.ContentFolderPath, file);
Image image = new Image();
BitmapImage src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri(pathToImage, UriKind.Absolute);
src.EndInit();
double ratio = src.Width / src.Height;
image.Source = src;
image.Stretch = Stretch.Uniform;
image.Height = canvas1.Height;
image.Width = canvas1.Height * ratio;
canvas1.Children.Add(image);
Canvas.SetTop(image, 0);
Canvas.SetLeft(image, -999);
textBlocks.AddLast(image);
}
catch (Exception ex)
{
HasError = true;
ErrorMessage = ex.Message;
}
}
void AddTextBlock(string Text, SolidColorBrush color)
{
try
{
double w = MeasureTextSize(Text, fontFamily, fontStyle, fontWeight, fontStretch, fontSize).Width;
TextBlock tb = new TextBlock();
tb.Text = Text;
tb.FontSize = 28;
tb.FontWeight = FontWeights.Normal;
tb.Foreground = color;
// tb.Background = Brushes.Blue;
tb.FontSize = fontSize = canvas1.Height / koeff;
tb.Width = w;
canvas1.Children.Add(tb);
Canvas.SetTop(tb, 0);
Canvas.SetLeft(tb, -9999);
textBlocks.AddLast(tb);
}
catch (Exception ex)
{
HasError = true;
ErrorMessage = ex.Message;
}
}
As a user specified in the comments, you should do this in XAML. It's easier, cleaner and yes, it is a best practice. You can use a ListBox of Items and just play with it's ItemsPanel data template. I also recommend further learning on Storyboards.