I am trying to use Aspose.Imaging version 21.7.0 to compress some .jpg and .png byte arrays.
My Winforms Click event:
private void btnConvert_Click(object sender, EventArgs e)
{
_context.Images.Load();
var images = _context.Images.Local.ToBindingList();
foreach (var image in images)
{
if (image.ImageData != null)
{
image.MimeType = MimeTypes.GetMimeType(image.Filename.Trim());
if (image.MimeType.StartsWith("image") && image.MimeType != "image/vnd.microsoft.icon")
{
byte[] newImage;
using (MemoryStream stream = new MemoryStream(image.ImageData))
{
using (RasterImage myImage = (RasterImage) Image.Load(stream))
{
switch (image.MimeType)
{
case "image/png":
PngOptions options = new PngOptions
{
CompressionLevel = 9,
ColorType = PngColorType.IndexedColor,
Progressive = true,
Palette = ColorPaletteHelper.GetCloseImagePalette(myImage, 256,
PaletteMiningMethod.Histogram)
};
using (MemoryStream memory = new MemoryStream())
{
myImage.Save(memory, options);
memory.Position = 0;
newImage = memory.ToArray();
}
break;
case "image/jpeg":
JpegOptions saveOptions = new JpegOptions
{
BitsPerChannel = 8,
CompressionType = JpegCompressionMode.Progressive,
Quality = 100,
ResolutionSettings = new ResolutionSetting(96.0, 96.0),
ResolutionUnit = ResolutionUnit.Inch,
ColorType = JpegCompressionColorMode.Cmyk,
Palette = ColorPaletteHelper.GetCloseImagePalette(myImage, 256, PaletteMiningMethod.Histogram)
};
using (MemoryStream memory = new MemoryStream())
{
Debug.WriteLine(image.Filename);
try
{
myImage.Save(memory, saveOptions); <<== Exceptions
}
catch (Exception exception)
{
Debug.WriteLine("Image Byte Array: " + image.ImageData);
}
memory.Position = 0;
newImage = memory.ToArray();
}
break;
default:
newImage = null;
break;
}
}
}
image.CompressedImageData = Compress(newImage);
}
else
{
image.CompressedImageData = null;
}
}
}
var count = _context.SaveChanges();
MessageBox.Show($#"{count} images compressed.");
}
I am getting alot of Exceptions with jpeg images. Example:
Exception thrown: ' ' in Aspose.Imaging.dll
Exception thrown: 'Aspose.Imaging.FileFormats.Dng.DngException' in Aspose.Imaging.dll
Exception thrown: ' ' in Aspose.Imaging.dll
Exception thrown: 'Aspose.Imaging.CoreExceptions.ImageSaveException' in Aspose.Imaging.dll
... all thrown from myImage.Save(memory, saveOptions) in the jpeg section.
Any help will be appreciated.
Since Aspose.Imaging is a paid product,
you should contact them at their site for support.
There is a free forum specially for Aspose products:
https://forum.aspose.com/
Everyone that have experienced with Aspose errors know that the errors are hard to understand due to their obfuscation of the code, so the best solution is to contact them directly.
Related
I am stuck. Currently I am trying to simulate pulling a binary blob from a database that is supposed to be a TIFF image. I use this gist image.tif in the image variable to do so. I am pretty sure I am close to making this happen. It's that the issue probably has to do with how I am converting the string to byte array or something. Basically this application throws an exception stating that it can't create a PDF with 0 frames. At this point I must admit that I may be in over my head on this one. Could someone be so kind and help me the rest of the way with this one?
The code is included below:
using System;
using System.Drawing;
using PdfSharp.Pdf;
using PdfSharp.Drawing;
using System.IO;
using System.Drawing.Imaging;
using System.Text;
namespace ConvertTifToPDFFile
{
class Program
{
static void Main(string[] args)
{
string image = "";
byte[] imageAsByteStream = Encoding.ASCII.GetBytes(image);
int imageByteStreamLength = imageAsByteStream.Length;
string base64EncodedImage = Convert.ToBase64String(imageAsByteStream);
imageAsByteStream = Encoding.ASCII.GetBytes(base64EncodedImage);
Stream imageStream = TiffImageSplitter.ByteArrayToMemoryStream(imageAsByteStream);
// Image splitImage = TiffImageSplitter.getTiffImage(imageStream, 1);
TiffImageSplitter.tiff2PDF(imageStream);
}
}
public class TiffImageSplitter
{
private static TiffImageSplitter tiff = new TiffImageSplitter();
public static void tiff2PDF(Stream imageByteStream)
{
PdfDocument doc = new PdfDocument();
int pageCount = getPageCount(imageByteStream);
for (int i = 0; i < pageCount; i++)
{
PdfPage page = new PdfPage();
Image img = getTiffImage(imageByteStream, 1);
XImage imgFrame = XImage.FromGdiPlusImage(img);
page.Width = imgFrame.PointWidth;
page.Height = imgFrame.PointHeight;
doc.Pages.Add(page);
XGraphics xgr = XGraphics.FromPdfPage(doc.Pages[i]);
xgr.DrawImage(img, 0, 0);
}
doc.Save("C:/temp/test.pdf");
doc.Close();
}
public static Image getTiffImage(Stream imageStream, int pageNumber)
{
MemoryStream ms = null;
Image returnImage = null;
try
{
ms = new MemoryStream();
Image sourceImage = Image.FromStream(imageStream, true, true);
Guid objGuid = sourceImage.FrameDimensionsList[0];
FrameDimension objDimension = new FrameDimension(objGuid);
sourceImage.SelectActiveFrame(objDimension, pageNumber);
sourceImage.Save(ms, ImageFormat.Tiff);
returnImage = Image.FromStream(ms);
}
catch (Exception ex)
{
Console.WriteLine("{0} Exception caught.", ex);
returnImage = null;
}
return returnImage;
}
public static MemoryStream ByteArrayToMemoryStream(byte[] bytestream)
{
MemoryStream stream = new MemoryStream();
stream.Write(bytestream, 0, bytestream.Length);
return stream;
}
public static int getPageCount(Stream imageStream)
{
int pageCount = -1;
try
{
Image img = Image.FromStream(imageStream, true, true);
pageCount = img.GetFrameCount(FrameDimension.Page);
img.Dispose();
}
catch (Exception ex)
{
Console.WriteLine("{0} Exception caught.", ex);
pageCount = 0;
}
return pageCount;
}
}
}
IMPORTANT!!!! First of all, your example tiff isn't valid at all. It can't be read by any file editor. I have had to take these ones for testing.
Then, the code has couple errors:
1) I don't understand what've done with strings but reading files and BLOBs are same:
static void Main(string[] args)
{
//string image = "";
//byte[] imageAsByteStream = Encoding.ASCII.GetBytes(image);
byte[] imageAsByteStream = File.ReadAllBytes("../../../MARBIBM.TIF");
//int imageByteStreamLength = imageAsByteStream.Length;
//string base64EncodedImage = Convert.ToBase64String(imageAsByteStream);
//imageAsByteStream = Encoding.ASCII.GetBytes(base64EncodedImage);
Stream imageStream = TiffImageSplitter.ByteArrayToMemoryStream(imageAsByteStream);
// Image splitImage = TiffImageSplitter.getTiffImage(imageStream, 1);
TiffImageSplitter.tiff2PDF(imageStream);
}
2) method tiff2PDF should be like that
public static void tiff2PDF(Stream imageByteStream)
{
PdfDocument doc = new PdfDocument();
int pageCount = getPageCount(imageByteStream);
for (int i = 0; i < pageCount; i++)
{
PdfPage page = new PdfPage();
Image img = getTiffImage(imageByteStream, i); //<---HERE WAS ANOTHER ERROR, LOOK AT i
XImage imgFrame = XImage.FromGdiPlusImage(img);
3)
public static MemoryStream ByteArrayToMemoryStream(byte[] bytestream)
{
MemoryStream stream = new MemoryStream(bytestream);
//stream.Write(bytestream, 0, bytestream.Length);
return stream;
}
In my scenario I have 3 or more multi-page tiff images which I need to merge into a single tiff image.
Below is the the code I have tried. It merges in to a single tiff image but only with first page of all tiff images.
private static void MergeTiff(string[] sourceFiles)
{
string[] sa = sourceFiles;
//get the codec for tiff files
ImageCodecInfo info = null;
foreach (ImageCodecInfo ice in ImageCodecInfo.GetImageEncoders())
if (ice.MimeType == "image/tiff")
info = ice;
//use the save encoder
Encoder enc = Encoder.SaveFlag;
EncoderParameters ep = new EncoderParameters(1);
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.MultiFrame);
Bitmap pages = null;
int frame = 0;
foreach (string s in sa)
{
if (frame == 0)
{
MemoryStream ms = new MemoryStream(File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, #"C:\Data_Warehouse\SVNRepository\CD.BNS.W5555.LT45555C.D180306.T113850.Z0101\", s)));
pages = (Bitmap)Image.FromStream(ms);
var appDataPath = #"C:\Data_Warehouse\SVNRepository\Tiffiles\";
var filePath = Path.Combine(appDataPath, Path.GetRandomFileName() + ".tif");
//save the first frame
pages.Save(filePath, info, ep);
}
else
{
//save the intermediate frames
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.FrameDimensionPage);
try
{
MemoryStream mss = new MemoryStream(File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, #"C:\Data_Warehouse\SVNRepository\CD.BNS.W5555.LT45555C.D180306.T113850.Z0101\", s)));
Bitmap bm = (Bitmap)Image.FromStream(mss);
pages.SaveAdd(bm, ep);
}
catch (Exception e)
{
//LogError(e, s);
}
}
if (frame == sa.Length - 1)
{
//flush and close.
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.Flush);
pages.SaveAdd(ep);
}
frame++;
}
}
I need to join multiple tiff images with all pages from each tiff image. Please advise!
Thanks
EDIT: Updated from below answer
if (frame == 0)
{
MemoryStream ms = new MemoryStream(File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, #"C:\OMTest\Working\", s)));
pages = (Bitmap)Image.FromStream(ms);
var appDataPath = #"C:\Data_Warehouse\SVNRepository\Tiffiles\";
var filePath = Path.Combine(appDataPath, Path.GetRandomFileName() + ".tif");
//save the first frame
pages.Save(filePath, info, ep);
//Save the second frame if any
int frameCount1 = pages.GetFrameCount(FrameDimension.Page);
if (frameCount1 > 1)
{
for (int i = 1; i < frameCount1; i++)
{
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.FrameDimensionPage);
pages.SelectActiveFrame(FrameDimension.Page, i);
pages.SaveAdd(pages, ep);
}
}
}
else
{
//save the intermediate frames
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.FrameDimensionPage);
try
{
MemoryStream mss = new MemoryStream(File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, #"C:\OMTest\Working\", s)));
Bitmap bm = (Bitmap)Image.FromStream(mss);
int frameCount = bm.GetFrameCount(FrameDimension.Page);
for (int i = 0; i < frameCount; i++)
{
bm.SelectActiveFrame(FrameDimension.Page, i);
pages.SaveAdd(bm, ep);
}
}
catch (Exception e)
{
//LogError(e, s);
}
}
You need to select the active frame to ensure you are getting all pages on the TIFF. In your code you need to get the count of frames and loop through these.
The code in your else block might look something like this:
MemoryStream mss = new MemoryStream(File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, #"C:\Data_Warehouse\SVNRepository\CD.BNS.W5555.LT45555C.D180306.T113850.Z0101\", s)));
Bitmap bm = (Bitmap)Image.FromStream(mss);
int frameCount = bm.GetFrameCount(FrameDimension.Page);
for(int i=0;i<frameCount;i++){
bm.SelectActiveFrame(FrameDimension.Page, i);
pages.SaveAdd(bm, ep);
}
You may have to tweak it as I haven't tested it.
The given code works great to merge single-page TIFF files into a single multi-page TIFF, however, if there are multi-page TIFF files as sources, it will only merge their first page in the resulting TIFF file: the other ones will be discarded.
Since we couldn't find any working samples that could work around this issue, we ended up coding a small C# helper class, which later became a full-fledged multi-platform console application written in .NET Core 2 and C#. We called the project MergeTIFF and we released the whole source code on GitHub under GNU v3 license, so that everyone else can use it as well; we also released the binaries for Windows and Linux (32-bit and 64-bit).
Here's the relevant excerpt of the C# code:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace MergeTiff.NET
{
/// <summary>
/// A small helper class to handle TIFF files
/// </summary>
public static class TiffHelper
{
/// <summary>
/// Merges multiple TIFF files (including multipage TIFFs) into a single multipage TIFF file.
/// </summary>
public static byte[] MergeTiff(params byte[][] tiffFiles)
{
byte[] tiffMerge = null;
using (var msMerge = new MemoryStream())
{
//get the codec for tiff files
ImageCodecInfo ici = null;
foreach (ImageCodecInfo i in ImageCodecInfo.GetImageEncoders())
if (i.MimeType == "image/tiff")
ici = i;
Encoder enc = Encoder.SaveFlag;
EncoderParameters ep = new EncoderParameters(1);
Bitmap pages = null;
int frame = 0;
foreach (var tiffFile in tiffFiles)
{
using (var imageStream = new MemoryStream(tiffFile))
{
using (Image tiffImage = Image.FromStream(imageStream))
{
foreach (Guid guid in tiffImage.FrameDimensionsList)
{
//create the frame dimension
FrameDimension dimension = new FrameDimension(guid);
//Gets the total number of frames in the .tiff file
int noOfPages = tiffImage.GetFrameCount(dimension);
for (int index = 0; index < noOfPages; index++)
{
FrameDimension currentFrame = new FrameDimension(guid);
tiffImage.SelectActiveFrame(currentFrame, index);
using (MemoryStream tempImg = new MemoryStream())
{
tiffImage.Save(tempImg, ImageFormat.Tiff);
{
if (frame == 0)
{
//save the first frame
pages = (Bitmap)Image.FromStream(tempImg);
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.MultiFrame);
pages.Save(msMerge, ici, ep);
}
else
{
//save the intermediate frames
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.FrameDimensionPage);
pages.SaveAdd((Bitmap)Image.FromStream(tempImg), ep);
}
}
frame++;
}
}
}
}
}
}
if (frame >0)
{
//flush and close.
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.Flush);
pages.SaveAdd(ep);
}
msMerge.Position = 0;
tiffMerge = msMerge.ToArray();
}
return tiffMerge;
}
}
}
For additional info and/or to download it, you can take a look at the following resources that we published to better document the whole project:
MergeTIFF on GitHub
Specifications, dependencies and other info
I am running a cron job in C# that takes 200,000 images and convert into 1 bit image. During running this job, sometimes the process crashes (even though I have global try catch), sometimes for some images(not all) it throws OutOfMemoryException and sometimes for some images it it throws A generic error occurred in GDI.
int pageSize = 1000;
for (int pageNumber = 0; pageNumber < 200; pageNumber++)
{
var imageUrls = allIMageUrls.Skip(pageSize * pageNumber).Take(pageSize).ToList();
var counter = 0;
var total = imageUrls.Count;
Logger.Log($"Page Number : {pageNumber}");
var failedImageUrls = new System.Collections.Concurrent.ConcurrentBag<string>();
Parallel.ForEach(imageUrls, imageUrl =>
{
try
{
Interlocked.Increment(ref counter);
var image = _httpService.DownloadImage(imageUrl);
if (image != null && image.Length > 0)
{
var oneBitImage = ConvertToOnebitFaxGroup4(contract);
_httpService.UploadImage(image, oneBitImage);
oneBitImage = null;
image = null;
}
}
catch (Exception ex)
{
failedImageUrls.Add(imageUrl);
Logger.Log(ex);
}
});
This is one time process. I added paging so that when it crashes I can restart from that page instead of start at beginning.
public static class ImageProcessor
{
static ImageCodecInfo _codecInfo;
static EncoderParameters _encoderParameters;
static ImageProcessor()
{
foreach (var codec in ImageCodecInfo.GetImageEncoders())
{
if (codec.MimeType == "image/tiff")
{
_codecInfo = codec;
break;
}
}
_encoderParameters = new EncoderParameters(2);
_encoderParameters.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionCCITT4);
_encoderParameters.Param[1] = new EncoderParameter(Encoder.ColorDepth, (long)1);
}
public static byte[] ConvertToOnebitFaxGroup4(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
var image = Image.FromStream(memoryStream);
var pData = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, pData, bytes.Length);
var bytesPerLine = (image.Width + 31) / 32 * 4;
var img = new Bitmap(image.Width, image.Height, bytesPerLine, PixelFormat.Format1bppIndexed, pData);
using (var ms = new MemoryStream())
{
image.Save(ms, _codecInfo, _encoderParameters);
img.Dispose();
Marshal.FreeHGlobal(pData);
return ms.ToArray();
}
}
}
Updated:
public static byte[] ConvertToOnebitFaxGroup4(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
using (var image = Image.FromStream(memoryStream))
{
var pData = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, pData, bytes.Length);
var bytesPerLine = (image.Width + 31) / 32 * 4;
using (var img = new Bitmap(image.Width, image.Height, bytesPerLine, PixelFormat.Format1bppIndexed, pData))
{
using (var ms = new MemoryStream())
{
img.Save(ms, _codecInfo, _encoderParameters);
Marshal.FreeHGlobal(pData);
return ms.ToArray();
}
}
}
}
}
Update2
public static byte[] ConvertToOnebitFaxGroup4(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
using (var image = Image.FromStream(memoryStream))
{
using (var ms = new MemoryStream())
{
image.Save(ms, _codecInfo, _encoderParameters);
return ms.ToArray();
}
}
}
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I'm getting an out of memory exception while looping through images. It happens after about 500 images.
if I try to run the same code through a parallel loop it only makes it through about 5 images.
It usually seems to slow down before throwing the out of memory exception
Here is my code. I'm using MagickNet
public static void PreProductionProcessing(DirectoryInfo dirInfo)
{
var tw = new StreamWriter(#"C:\bar.csv", true);
tw.WriteLine("Filename, Alpha Channel Removed, Dpi Changed, Resized");
foreach (var currentFile in dirInfo.GetFiles("*.tif"))
{
var alphaChannelRemoved = false;
var resized = false;
var DpiChanged = false;
Image img = null;
MemoryStream ms = null;
try
{
img = new Image(currentFile.FullName);
if (img.Matte)
{
ms = RemoveAlphaChanell(currentFile.FullName);
img = new Image(ms);
alphaChannelRemoved = true;
}
if (img.Density.x_res < 300)
{
img.Density = new Image.Resolution(300, 300);
DpiChanged = true;
}
if (img.Size.Width != 1875)
{
var newSize = img.Size;
double resizeRatio = (double)newSize.Width / (double)1875;
newSize.Width = Convert.ToInt16(img.Size.Width / resizeRatio);
newSize.Height = Convert.ToInt16(img.Size.Height / resizeRatio);
img.Resize(newSize);
resized = true;
}
using (var filestream = new FileStream(Path.Combine(#"C:\OutFolder", currentFile.Name), FileMode.CreateNew))
{
img.Write(filestream, "tif");
}
tw.WriteLine("{0}, {1}, {2}, {3}", currentFile.Name, alphaChannelRemoved, DpiChanged, resized);
tw.Flush();
}
catch (Exception e)
{
tw.WriteLine("{0}, {1}", currentFile.Name, e.Message);
tw.Flush();
}
finally
{
if (img != null)
{
img.Dispose();
img = null;
}
if (ms != null)
ms.Dispose();
Magick.Term();
}
}
}
static MemoryStream RemoveAlphaChanell(string source)
{
Bitmap old = new Bitmap(source);
Bitmap temp = new Bitmap(old.Width, old.Height, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(temp);
g.Clear(System.Drawing.Color.White);
var rect = new Rectangle(Point.Empty, new Size(old.Width, old.Height));
g.DrawImage(old, rect);
var stream = new MemoryStream();
temp.Save(stream, ImageFormat.Tiff);
stream.Seek(0, SeekOrigin.Begin);
old.Dispose();
temp.Dispose();
g.Dispose();
return stream;
}
I'm not sure if the memory leak is within MagickNet or if anyone can see anything in my code that is causing this issue.
Any suggestions will be greatly appreciated
When img.Matte is true, you replace the image in the img variable with a new image. The previous image is never disposed.
Dispose the previous image before you replace it:
if (img.Matte)
{
img.Dispose();
ms = RemoveAlphaChanell(currentFile.FullName);
img = new Image(ms);
alphaChannelRemoved = true;
}
Whenever I retrieve an image using my Generic Handler, I retrieve either an empty image or a broken image.
Here is my code.
aspx File:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
//imports
using DHELTASSys.Modules;
using System.Data;
using DHELTASSys.AuditTrail;
namespace DHELTASSys
{
public partial class EvaluateOffense : System.Web.UI.Page
{
DisciplineModuleBL discipline = new DisciplineModuleBL();
DHELTASSysAuditTrail audit = new DHELTASSysAuditTrail();
protected void Page_Load(object sender, EventArgs e)
{
string position = Session["Position"].ToString();
if (Session["EmployeeID"] == null)
{
Response.Redirect("LogIn.aspx");
} else if(position != "HR Manager")
{
Response.Redirect("AccessDenied.aspx");
}
discipline.Offense_emp_id = int.Parse(Session["OffenseID"].ToString());
DataTable dt = discipline.GetProof();
if (dt.Rows == null)
{
Label9.Visible = false;
Image1.Visible = false;
}
}
protected void btnEvaluate_Click(object sender, EventArgs e)
{
discipline.Offense_emp_id = int.Parse(Session["OffenseID"].ToString());
discipline.Decision = drpDecision.Text;
discipline.AddOffenseDecision();
audit.Emp_id = int.Parse(Session["EmployeeID"].ToString());
audit.AddAuditTrail(drpDecision.Text + "ed Employee's offense.");
}
}
}
Here is the handler:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
//imports
using System.Data;
using DHELTASSys.Modules;
using DHELTASSys.DataAccess;
namespace DHELTASSys
{
public class ShowImage : IHttpHandler, System.Web.SessionState.IRequiresSessionState
{
DisciplineModuleBL discipline = new DisciplineModuleBL();
public void ProcessRequest(HttpContext context)
{
if (context.Session["OffenseID"].ToString() == null) return;
int offense_emp_id = int.Parse(context.Session["OffenseID"].ToString());
discipline.Offense_emp_id = offense_emp_id;
DataTable dt = discipline.GetProof();
if (dt.Rows == null) return;
int id = 1;
string image = dt.Rows[0][1].ToString() + id;
string FileName = dt.Rows[0][0].ToString();
string FileContentType = dt.Rows[0][2].ToString();
Byte[] bytes = (Byte[])dt.Rows[0][1];
string imageBase64 = Convert.ToBase64String(bytes);
context.Response.ContentType = "image/" + FileContentType;
if (context.Request.QueryString["id"] == "1")
{
MemoryStream ms = new MemoryStream();
ms.Write(bytes, 0, bytes.Length);
context.Response.Buffer = true;
System.Drawing.Image imagen = System.Drawing.Image.FromStream(ms);
context.Response.BinaryWrite(bytes);
ms.Dispose();
}
else
{
return;
}
}
public bool IsReusable
{
get
{
return true;
}
}
}
}
And adding to that, here is my image object.
<asp:Image ID="Image1" runat="server" ImageUrl="~/ShowImage.ashx" />
I already tweaked my code in so many ways.
The image file is stored in SQL Server using the data type "Image"
As you can see, I'm using the session to retrieve the specified image from the Database.
I have no problem in accessing the session whatsoever.
Thanks in advance.
Your code seems a bit more complicated than necessary; you can write the binary data to the outputstream without needing to load it into a memory stream, and you're doing nothing with your System.Drawing.Image object. Try this:
context.Response.OutputStream.Write(bytes, 0, bytes.Length);
First, I don't see anything wrong with the way you are writing the image to the response stream. There's a few useless lines of code but I understand that as you said, you were tweaking your code in desperation. Basically, this should be good enough...
Byte[] bytes = (Byte[])dt.Rows[0][1];
context.Response.ContentType = "image/" + FileContentType;
if (context.Request.QueryString["id"] == "1")
{
context.Response.BinaryWrite(bytes);
context.ApplicationInstance.CompleteRequest(); //just to make sure the ASP.NET pipeline completes the request
}
else
{
return;
}
Now, that "should" work given that bytes has been correctly casted to a byte array. Make sure to add some proper exception handling and logging because I'm a bit suspicious that the problem it's somewhere else. So, follow these steps:
Clean up your code for better clarity
Debug the app
Implement some exception handling
Implement some sort of error logging
You should be able to get to the bottom of this issue since there's nothing wrong in sending an array of bytes using the BinaryWrite method
This is real example that pickup from my project
into page.cs set image url dynamically:
// for diffrent url using guid in url
imgProfilePic.ImageUrl = "GenericHandler_ShowImage.ashx?Ref=" + Guid.NewGuid().ToString() + "&n=" + lngEmployeeID;
into handler, get image by table adapter
// in handler
public void ProcessRequest(HttpContext context)
{
long EmployeeID = -1;
if (context.Request.QueryString["n"] != null)
EmployeeID = long.Parse(context.Request.QueryString["n"].ToString());
//else
// throw new ArgumentException("No parameter specified");
if (context.Request.QueryString["actid"] == "2")
{
ShowThumbPic(context, EmployeeID);
return;
}
//else ...
}
private void ShowThumbPic(HttpContext context, long EmployeeID)
{
context.Response.ContentType = "image/jpeg";
Stream myStream = GetEmpImage(EmployeeID);
byte[] myImgByteArray;
using (BinaryReader br = new BinaryReader(myStream))
{
myImgByteArray = br.ReadBytes((int)myStream.Length);
}
MemoryStream ms = new MemoryStream(byteArrayIn);
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
if (img.Height > 50 || img.Width > 50)
{
System.Drawing.Size siz = GetScaledSize(img.Size, new System.Drawing.Size(50, 50));
img = (System.Drawing.Image)ResizeImage(img, siz);
}
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] myBuffer = ms.ToArray();
int byteSeq = myBuffer.Length; //myStream.Read(myBuffer, 0, 4096);
if (byteSeq > 0)
context.Response.OutputStream.Write(myBuffer, 0, byteSeq);
}
private System.Drawing.Image GetEmployeeImage(long EmployeeID)
{
System.Drawing.Image img = null;
try
{
using (DAL.dstEmployeeTableAdapters.tbl_Employee_InfoTableAdapter ta = new DAL.dstEmployeeTableAdapters.tbl_Employee_InfoTableAdapter())
{
object obj = ta.spr_Employee_Info_GetPicture(EmployeeID);
if (obj != null)
{
MemoryStream ms = new MemoryStream((byte[])obj);
img = System.Drawing.Image.FromStream(ms);
}
}
}
catch (Exception x)
{
throw new Exception(Msg.Error_InDownloadPicture + x.Message);
}
return img;
}
public static Size GetScaledSize(Size ImageSize, Size FrameSize)
{
int newWidth = ImageSize.Width;
int newHeight = ImageSize.Height;
double ratioX = (double)FrameSize.Width / ImageSize.Width;
double ratioY = (double)FrameSize.Height / ImageSize.Height;
double ratio = Math.Min(ratioX, ratioY);
if (ratio < 1.0f) // if Frame is greater than image, resize it.
{
newWidth = (int)(ImageSize.Width * ratio);
newHeight = (int)(ImageSize.Height * ratio);
}
return new Size(newWidth, newHeight);
}
public static System.Drawing.Bitmap ResizeImage(System.Drawing.Image image, Size siz)
{
//a holder for the result
Bitmap result = new Bitmap(siz.Width, siz.Height);
// set the resolutions the same to avoid cropping due to resolution differences
result.SetResolution(image.HorizontalResolution, image.VerticalResolution);
//use a graphics object to draw the resized image into the bitmap
using (Graphics graphics = Graphics.FromImage(result))
{
//set the resize quality modes to high quality
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//draw the image into the target bitmap
graphics.DrawImage(image, 0, 0, result.Width, result.Height);
}
//return the resulting bitmap
return result;
}