Printing an array of images - c#

I inherited an app that needs to print an array of images which are stored in a database. I have written the code to retrieve the images via a web service, and have put the images into an array of BitmapImage.
However when I add the BitmapImage to the source of the Image, the image is then empty. No exceptions are thrown, but it appears that no images are added to the list, and the code appears to simply halt as soon as I add the image to the array.
Any hints would be appreciated.
In header of class:
\\BitmapImage is System.Windows.Media.Imaging.BitmapImage
public List<BitmapImage> prtImages;
Event handler for web service on completion of getting images asynchronously:
void client_GetImagesCompleted(object sender, OrderImageWebService.GetOrderImagesCompletedEventArgs e)
{
if (e.Error != null)
{
System.Windows.Browser.HtmlPage.Window.Eval("alert('Error occurred loading images.');");
throw new Exception(string.Format("Error loading image edits: {0}", e.Error));
}
else if ((!e.Cancelled) && (e.Result != null))
{
try
{
for (int i = 0; i <= imgs; i++)
{
byte[] bImage = loi[i].Content;
using (System.IO.MemoryStream sioms =
new System.IO.MemoryStream(bImage, 0, bImage.Length))
{
bi.SetSource(sioms);
int ph = bi.PixelHeight; //Alert shows 3296
int pw = bi.PixelWidth; //Alert shows 2560
System.Windows.Browser.HtmlPage.Window.Eval(
string.Format("alert('BI image is {0} by {1}.');",
ph.ToString(), pw.ToString()));
prtImages.Add(bi);
//This alert never shows
System.Windows.Browser.HtmlPage.Window.Eval(
string.Format("alert('prtImages has size {1} after add.');",
prtImages.Count.ToString()));
}
}
}
catch(Exception ex)
{
//This exception is never caught
System.Windows.Browser.HtmlPage.Window.Eval(string.Format("alert('{0}');", ex.Message));
}
}
else
{
System.Windows.Browser.HtmlPage.Window.Eval("alert('Oops. Error.');");
}
System.Windows.Browser.HtmlPage.Window.Eval("alert('Clearing wait.');");
bPrtImageLoaded = true;
ewh_gotImages.Set();
}
In GetPrintImage:
public Image GetPrintImage(int iPageID)
{
if (bPrtImageLoaded)
{
Image img = new Image();
img.Source = prtImages[iPageID];
double ah = img.ActualHeight;
double aw = img.ActualWidth;
System.Windows.Browser.HtmlPage.Window.Eval(
string.Format("alert('Image is {0} by {1}.');",
ah.ToString(), aw.ToString()));
if (null != img)
{
return (img);
}
}
return(null);
}
Called from button click
private void p_printMultiplePages(object sender, System.Windows.Printing.PrintPageEventArgs e)
{
Image img = GetPrintImage(iCurPrintPage);
if (null != img)
{
if (e.PrintableArea.Height < img.ActualHeight)
{
scale = e.PrintableArea.Height / img.ActualHeight;
}
if ((e.PrintableArea.Width < img.ActualWidth) && ((e.PrintableArea.Width / img.ActualWidth) < scale))
{
scale = e.PrintableArea.Width / img.ActualWidth;
}
if (scale < 1)
{
scaleTransform.ScaleX = scale;
scaleTransform.ScaleY = scale;
img.RenderTransform = scaleTransform;
}
e.PageVisual = img;
iCurPrintPage++;
if (iCurPrintPage < SessionState.PageCount)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
}
}
else
{
System.Windows.Browser.HtmlPage.Window.Eval(
string.Format("alert('Image {0} of order {1} is null.');",
iCurPrintPage.ToString(), SessionState.OrderID.ToString()));
e.HasMorePages = false;
}
}
Thanks for any hints you might have,
Bruce.

I would suggest getting images from web service as binary data (byte[] ) encoded each image as base64 and publish array of base64 strings. On the client you will decode each element of array with base64 stings back to byte[]. Read it with MemoryStream and pass that object to your Image reader (read this one reading image from bytes)
But before you do anything of that, make sure that your p_printMultiplePages method can display local images

Related

How to extract rotated images from PDF with iText

I need to extract images from PDF.
I know that some images are rotated 90 degrees (I checked with online tools).
I'm using this code:
PdfRenderListener:
public class PdfRenderListener : IExtRenderListener
{
// other methods ...
public void RenderImage(ImageRenderInfo renderInfo)
{
try
{
var mtx = renderInfo.GetImageCTM();
var image = renderInfo.GetImage();
var fillColor = renderInfo.GetCurrentFillColor();
var color = Color.FromArgb(fillColor?.RGB ?? Color.Empty.ToArgb());
var fileType = image.GetFileType();
var extension = "." + fileType;
var bytes = image.GetImageAsBytes();
var height = mtx[Matrix.I22];
var width = mtx[Matrix.I11];
// rotated image
if (height == 0 && width == 0)
{
var h = Math.Abs(mtx[Matrix.I12]);
var w = Math.Abs(mtx[Matrix.I21]);
}
// save image
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
When I save images with this code the rotated images are saved with distortion.
I have read this post iText 7 ImageRenderInfo Matrix contains negative height on Even number Pages and mkl answer.
In current transfromation matrix (mtx) I have these values:
0
841.9
0
-595.1
0
0
595.1
0
1
I know image rotated 90 degrees. How can I transform an image to get a normal image?
As #mkl mentioned, the true reason was not in the rotation of the image, but with the applied filter.
I analyzed the pdf file with iText RUPS and found that the image was encoded with a CCITTFaxDecode filter:
RUPS screen
Next, I looked for ways to decode this filter and found these questions
Extracting image from PDF with /CCITTFaxDecode filter.
How to use Bit Miracle LibTiff.Net to write the image to a MemoryStream
I used the BitMiracle.LibTiff.NET library
I wrote this method:
private byte[] DecodeInternal(byte[] rawBytes, int width, int height, int k, int bitsPerComponent)
{
var compression = GetCompression(k);
using var ms = new MemoryStream();
var tms = new TiffStream();
using var tiff = Tiff.ClientOpen("in-memory", "w", ms, tms);
tiff.SetField(TiffTag.IMAGEWIDTH, width);
tiff.SetField(TiffTag.IMAGELENGTH, height);
tiff.SetField(TiffTag.COMPRESSION, compression);
tiff.SetField(TiffTag.BITSPERSAMPLE, bitsPerComponent);
tiff.SetField(TiffTag.SAMPLESPERPIXEL, 1);
var writeResult = tiff.WriteRawStrip(0, rawBytes, rawBytes.Length);
if (writeResult == -1)
{
Console.WriteLine("Decoding error");
}
tiff.CheckpointDirectory();
var decodedBytes = ms.ToArray();
tiff.Close();
return decodedBytes;
}
private Compression GetCompression(int k)
{
return k switch
{
< 0 => Compression.CCITTFAX4,
0 => Compression.CCITTFAX3,
_ => throw new NotImplementedException("K > 0"),
};
}
After decoding and rotating the image, I was able to save a normal image. Thanks everyone for the help.
You can try this. I'm using Itext 7 for java. Here you still need to write your own listener:
public class MyImageRenderListener implements IEventListener {
protected String path;
protected String extension;
public MyImageRenderListener (String path) {
this.path = path;
}
public void eventOccurred(IEventData data, EventType type) {
switch (type) {
case RENDER_IMAGE:
try {
String filename;
FileOutputStream os;
ImageRenderInfo renderInfo = (ImageRenderInfo) data;
PdfImageXObject image = renderInfo.getImage();
if (image == null) {
return;
}
byte[] imageByte = image.getImageBytes(true);
extension = image.identifyImageFileExtension();
filename = String.format(path, image.getPdfObject().getIndirectReference().getObjNumber(), extension);
os = new FileOutputStream(filename);
os.write(imageByte);
os.flush();
os.close();
} catch (com.itextpdf.io.exceptions.IOException | IOException e) {
System.out.println(e.getMessage());
}
break;
default:
break;
}
}
public Set<EventType> getSupportedEvents() {
return null;
}
}
I checked for a pdf with a random rotation angle, and 90 degrees, the resulting picture was obtained without distortion
public void manipulatePdf() throws IOException, SQLException, ParserConfigurationException, SAXException {
PdfDocument pdfDoc = new PdfDocument(new PdfReader("path to pdf"), new PdfWriter(new ByteArrayOutputStream()));
MyImageRenderListener listener = new MyImageRenderListener("path to resulting image");
PdfCanvasProcessor parser = new PdfCanvasProcessor(listener);
for (int i = 1; i <= pdfDoc.getNumberOfPages(); i++) {
parser.processPageContent(pdfDoc.getPage(i));
}
pdfDoc.close();
}

C# - Updating pictureBox.Image during Runtime causes Error

i am trying to change the pictureBox.Image during Runtime. I have several Model classes with a picture stored, whenever i click on a MenuStripItem i call the method "ChangePictureBoxImages". Till then there is no error (the pB is invisible!) but once i call the method to make the pB visible i get an Error. The Error code: "An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll".
Research said i should dispose the picturebox and set it to "null", however this does NOT help.
My Code:
using (Image current = BitmapManipulator.EvaluateMesurement(CSV_Name1, max_Rows, max_Col, var.TopImage, var.BitmapToManipulate, pB_ColourScale_Evaluation.Image, var.BitmapToManipulate, var.Filepath, var.FoldID))
{
var.LastEvaluationImage = current;
BitmapManipulator.CombineImagesAndSaveThem_Evaluation(var.TopImage, var.BitmapToManipulate, pB_ColourScale_Evaluation.Image, var.Filepath, var.FoldID); //saves the Files as jpg
if (var.CurrentlyShownToUser) //checks if the MenuStripItem is the active one
{
if (var.LastEvaluationImage == null) { MessageBox.Show("the image is null");} //only for debugging purpose -> does never call
ChangePictureBoxImages();
}
}
and the ChangePictureBoxImages():
public void ChangePictureBoxImages()
{
foreach (Fold fold in FoldExisting)
{
if (fold.FoldID == LastSelectedMenuStripItem_Name) //the clicked item is the last Selected MenuStripItem
{
if (fold.LastEvaluationImage != null)
{
Debug.WriteLine(pB_Evaluation_Bottom.Image.ToString() + " " + fold.LastEvaluationImage.ToString());
pB_Evaluation_Bottom.Image = fold.LastEvaluationImage;
}
pB_Evaluation_Top.Image = fold.TopImage;
}
}
}
There is no error till then, the error appears once i call "pB_Evaluation_Bottom.visible = true". (or if i called the visible method first first the error appears upon changing the Image!) The error also appears upon clicking 2 times on the MenuStripItem. I load the picture from the Class Fold as following:
This will set an image in the fold class, this image will then be manipulated and stored in LastEvaluationImage
private void setTheImages(string PictureToManipulate, string PathToTopImage)
{
try
{
this.BitmapToManipulate_intern = (Image)Image.FromFile(#PictureToManipulate, true);
this.TopImage_intern = (Image)Image.FromFile(#PathToTopImage, true);
}
catch (ArgumentNullException ex)
{
Debug.WriteLine("The BitMap for the manipulation process and the top image is not created.");
}
}
and the LastEvaluationImage where the last picture is stored -> this will be called to be the new pb.Image
private Image LastEvaluationImage_intern;
public Image LastEvaluationImage
{
get
{
return this.LastEvaluationImage_intern;
}
set
{
if (LastEvaluationImage_intern != null) { LastEvaluationImage_intern.Dispose(); LastEvaluationImage_intern = null; }
this.LastEvaluationImage_intern = value;
this.LastEvaluationTime_intern = DateTime.Now;
}
}
I know this is a little complex, but i hope someone can help me.
THANKS IN ADVANCE!
UPDATE: The Error must be in the following Code:
The BitmapManipulator.EvaluateMeasurement Code :
public Image EvaluateMesurement(double[][] MeasuredValues, int max_Rows, int max_Col, Image pB_Evaluation_Top, Image pB_Evaluation_Bottom, Image pB_EvaluationColourScale, Image ManipulatedBitmap, string PathMeasurementFiles, string Foldname)
{
using (Bitmap bitmap = new Bitmap(ManipulatedBitmap))
{
// the data array sizes:
int number_nio = 0;
int number_total = 0;
List<FileInfo> LastFiles;
int got_number_for_trends = Properties.Settings.Default.TrendNumber;
SolidBrush myBrush = new SolidBrush(red);
using (Graphics g = Graphics.FromImage(bitmap))
{
Random rnd = new Random(8);
int[,] data = new int[max_Col, max_Rows];
// scale the tile size:
float sx = 1f * bitmap.Width / data.GetLength(0);
float sy = 1f * bitmap.Height / data.GetLength(1);
LastFiles = FM.GetLastFiles_Trend(ref got_number_for_trends, PathMeasurementFiles);
double[][] CSV_Statistiken = FM.LastFilesToCSV(got_number_for_trends, true, LastFiles, PathMeasurementFiles);
for (int x = 0; x < max_Col; x++)
{
for (int y = max_Rows - 1; y >= 0; y--)
{
number_total++;
RectangleF r = new RectangleF(x * sx, y * sy, sx, sy);
if (MeasuredValues[y][x] < Properties.Settings.Default.Threshhold)
{
number_nio++;
if (CSV_Statistiken[y][x] == Properties.Settings.Default.TrendNumber)
{
myBrush.Color = Color.FromArgb(150, black);
g.FillRectangle(myBrush, r);
}
else
{
myBrush.Color = Color.FromArgb(150, red);
g.FillRectangle(myBrush, r);
}
}
else
{
myBrush.Color = Color.FromArgb(150, green);
g.FillRectangle(myBrush, r);
}
}
}
}
return bitmap;
}
}
This returned bitmap will be stored in fold.LastEvaluationImage as following:
using (Image current = BitmapManipulator.EvaluateMesurement(CSV_Name1, max_Rows, max_Col, var.TopImage, var.BitmapToManipulate, pB_ColourScale_Evaluation.Image, var.BitmapToManipulate, var.Filepath, var.FoldID))
{
var.LastEvaluationImage = current;
}
You're returning a disposed bitmap. It shouldn't be surprising you can't draw something that no longer exists :)
The using (bitmap) is the last thing you want in this case. The bitmap must survive longer than the scope of the using. And the using (current) in the caller has the same problem - you're again disposing the image way too early. You can only dispose it when it's clear that it isn't going to be used ever again - e.g. when you replace it with a new image.
To elaborate, using does nothing but call Dispose when you leave its scope. In the case of Bitmap (which is just a "thin" wrapper around a GDI bitmap), this releases the memory where the actual image data is stored. There isn't anything interesting left, so there's nothing to draw (and you'd basically be calling DrawBitmap(NULL) as far as GDI is concerned).

WPF AForge.net resize web cam image to custom size

Hey all I am trying to figure out a way of customizing the size of the webcam image inside an image control.
Currently this is the code that draws the image:
private void video_NewFrame(object sender, Video.NewFrameEventArgs eventArgs)
{
try
{
BitmapImage bi;
ResizeBicubic filter = new ResizeBicubic(400, 300);
using (var bitmap = (Bitmap)eventArgs.Frame.Clone())
{
bi = bitmap.ToBitmapImage();
}
bi.Freeze(); // avoid cross thread operations and prevents leaks
Dispatcher.BeginInvoke(new ThreadStart(delegate { videoPlayer.Source = bi; }));
}
catch (Exception exc)
{
MessageBox.Show("Error on _videoSource_NewFrame:\n" + exc.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
StopCamera();
}
}
As you see I am trying to use ResizeBicubic filter = new ResizeBicubic(400, 300); to resize it but I can not seem to find anywhere to put the filter.Apply().
If I do something like this:
filter.Apply(bi);
It gives me the error of:
Argument 1: cannot convert from 'System.Windows.Media.Imaging.BitmapImage' to 'System.Drawing.Bitmap'
I also have code that finds the largest video res that particular web cam can do:
private void StartCamera()
{
if (CurrentDevice != null)
{
_videoSource = new VideoCaptureDevice(CurrentDevice.MonikerString);
if (_videoSource.VideoCapabilities.Length > 0)
{
string highestSolution = "0;0";
//Search for the highest resolution
for (int i = 0; i < _videoSource.VideoCapabilities.Length; i++)
{
if (_videoSource.VideoCapabilities[i].FrameSize.Width > Convert.ToInt32(highestSolution.Split(';')[0]))
highestSolution = _videoSource.VideoCapabilities[i].FrameSize.Width.ToString() + ";" + i.ToString();
}
_videoSource.VideoResolution = _videoSource.VideoCapabilities[Convert.ToInt32(highestSolution.Split(';')[1])];
}
_videoSource.NewFrame += video_NewFrame;
_videoSource.Start();
}
}
And that code does work to set the image to the largest size on the screen but like I said, I want to customize that size to whatever the actual image control is sized to.
Any help would be great!

How to reduce image file, resize without losing quality using MultipleFileUpload in ASP.NET C#

I am uploading multiple photos using MultipleFileUpload, if I will upload big size images, then in slider image is not fixed size not showing proper looks. Is there any code for while uploading time restricts the size of images of the gallery.
Below is my c# code:
protected void lnkbtn_Submit_Click(object sender, EventArgs e)
{
try
{
if (MultipleFileUpload.HasFiles)
{
int MaxGalleryId, ReturnValue;
ReturnValue = obj.fnCreateNewPhotoGallery(txtGalleryName.Text, txtGalleryDescrption.Text, DateTime.Now, out MaxGalleryId);
if (ReturnValue != 0)
{
string GalleryPath = System.Configuration.ConfigurationManager.AppSettings["GalleryPath"] + MaxGalleryId;
Directory.CreateDirectory(Server.MapPath(GalleryPath));
string ThumbnailPath = System.Configuration.ConfigurationManager.AppSettings["ThumbnailPath"] + MaxGalleryId;
Directory.CreateDirectory(Server.MapPath(ThumbnailPath));
StringBuilder UploadedFileNames = new StringBuilder();
foreach (HttpPostedFile uploadedFile in MultipleFileUpload.PostedFiles)
{
//Upload file
string FileName = HttpUtility.HtmlEncode(Path.GetFileName(uploadedFile.FileName));
string SaveAsImage = System.IO.Path.Combine(Server.MapPath(GalleryPath + "/"), FileName);
uploadedFile.SaveAs(SaveAsImage);
//Create thumbnail for uploaded file and save thumbnail on disk
Bitmap Thumbnail = CreateThumbnail(SaveAsImage, 200, 200);
string SaveAsThumbnail = System.IO.Path.Combine(Server.MapPath(ThumbnailPath + "/"), FileName);
Thumbnail.Save(SaveAsThumbnail);
}
HTMLHelper.jsAlertAndRedirect(this, "Gallery created successfully. ", "Album.aspx?GalleryId=" + MaxGalleryId);
}
}
}
catch
{
HTMLHelper.jsAlertAndRedirect(this, "Gallery is not created. Some exception occured ", "CreateAlbum.aspx");
}
}
Below is my Create Thumbnail method code :
public Bitmap CreateThumbnail(string ImagePath, int ThumbnailWidth, int ThumbnailHeight)
{
System.Drawing.Bitmap Thumbnail = null;
try
{
Bitmap ImageBMP = new Bitmap(ImagePath);
ImageFormat loFormat = ImageBMP.RawFormat;
decimal lengthRatio;
int ThumbnailNewWidth = 0;
int ThumbnailNewHeight = 0;
decimal ThumbnailRatioWidth;
decimal ThumbnailRatioHeight;
// If the uploaded image is smaller than a thumbnail size the just return it
if (ImageBMP.Width <= ThumbnailWidth && ImageBMP.Height <= ThumbnailHeight)
return ImageBMP;
// Compute best ratio to scale entire image based on larger dimension.
if (ImageBMP.Width > ImageBMP.Height)
{
ThumbnailRatioWidth = (decimal)ThumbnailWidth / ImageBMP.Width;
ThumbnailRatioHeight = (decimal)ThumbnailHeight / ImageBMP.Height;
lengthRatio = Math.Min(ThumbnailRatioWidth, ThumbnailRatioHeight);
ThumbnailNewWidth = ThumbnailWidth;
decimal lengthTemp = ImageBMP.Height * lengthRatio;
ThumbnailNewHeight = (int)lengthTemp;
}
else
{
ThumbnailRatioWidth = (decimal)ThumbnailWidth / ImageBMP.Width;
ThumbnailRatioHeight = (decimal)ThumbnailHeight / ImageBMP.Height;
lengthRatio = Math.Min(ThumbnailRatioWidth, ThumbnailRatioHeight);
ThumbnailNewHeight = ThumbnailHeight;
decimal lengthTemp = ImageBMP.Width * lengthRatio;
ThumbnailNewWidth = (int)lengthTemp;
}
Thumbnail = new Bitmap(ThumbnailNewWidth, ThumbnailNewHeight);
Graphics g = Graphics.FromImage(Thumbnail);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.FillRectangle(Brushes.White, 0, 0, ThumbnailNewWidth, ThumbnailNewHeight);
g.DrawImage(ImageBMP, 0, 0, ThumbnailNewWidth, ThumbnailNewHeight);
ImageBMP.Dispose();
}
catch
{
return null;
}
return Thumbnail;
}
The above code there is a command line //Upload file from there uploading images. I used this example for the gallery:
http://www.bugdebugzone.com/2013/10/create-dynamic-image-gallery-slideshow.html
You can the ContentLength property of uploadedFile as such:
if (uploadedFile.ContentLength > 1000000)
{
continue;
}
ContentLength is the size in bytes of the uploaded file.
https://msdn.microsoft.com/en-us/library/system.web.httppostedfile.contentlength(v=vs.110).aspx

Memory Leaks : ListView with Bitmaps

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

Categories

Resources