Welcome Guest! To enable all features, please Login or Register.

Notification

Icon
Error

Options
View
Last Go to last post Unread Go to first unread post
#1 Posted : Wednesday, May 10, 2017 1:22:36 PM(UTC)
Toadfish

Groups: Registered
Posts: 11


I'm looking at the following location and I'm looking at the Load method from C:\LEADTOOLS 19\Examples\REST\Leadtools.RESTServices\Raster\Raster.cs.

I've made a Load method similar to this method called LoadFromData but I've modified it to take in Base64 encoded image data instead of a URL.
Here is the original code that I have copied from:

Code:

public Stream Load(string uri, int pageNumber, int resolution, string mimeType, int bitsPerPixel, int qualityFactor, int width, int height)
{
   // uri is not optional
   if (string.IsNullOrEmpty(uri))
      throw new ArgumentNullException("uri");

   if (pageNumber < 0)
      throw new ArgumentException("'pageNumber' must be a value greater than or equals to 0");

   // Default is page 1
   if (pageNumber == 0)
      pageNumber = 1;

   if (resolution < 0)
      throw new ArgumentException("'resolution' must be a value greater than or equals to 0");

   // Sanity check on other parameters
   if (qualityFactor < 0 || qualityFactor > 100)
      throw new ArgumentException("'qualityFactor' must be a value between 0 and 100");

   if (width < 0 || height < 0)
      throw new ArgumentException("'width' and 'height' must be value greater than or equal to 0");

   // Get the image format
   SaveImageFormat saveFormat = SaveImageFormat.GetFromMimeType(mimeType);

   // Use a temp file, much faster than calling Load/Info from a URI directly
   // In a production service, you might want to create a caching mechanism
   string tempFile = Path.GetTempFileName();
   try
   {
      // Force the uri to be fully qualified, reject everything else for security reasons
      Uri fullyQualifiedUri = new Uri(uri, UriKind.Absolute);
      if (fullyQualifiedUri.IsFile || fullyQualifiedUri.IsUnc)
         throw new Exception("URL cannot be local file or UNC path.");

      // Download the file
      using (WebClient client = new WebClient())
         client.DownloadFile(fullyQualifiedUri, tempFile);

      using (RasterCodecs codecs = new RasterCodecs())
      {
         ServiceHelper.InitCodecs(codecs, resolution);

         // Load the page
         using (RasterImage image = codecs.Load(tempFile, 0, CodecsLoadByteOrder.BgrOrGray, pageNumber, pageNumber))
         {
            // Resize it (will only resize if both width and height are not 0), will also take care of FAX images (with different resolution)
            ImageResizer.ResizeImage(image, width, height);

            // We need to find out the format, bits/pixel and quality factor
            // If the user gave as a format, use it
            if (saveFormat == null)
            {
               // If the user did not give us a format, use PNG
               saveFormat = new PngImageFormat();
               mimeType = "image/png";
            }

            saveFormat.PrepareToSave(codecs, image, bitsPerPixel, qualityFactor);

            // Save it to a memory stream
            MemoryStream ms = new MemoryStream();
            codecs.Save(image, ms, saveFormat.ImageFormat, saveFormat.BitsPerPixel);
            ms.Position = 0;

            // Set the MIME type and Content-Type if there is a valid web context
            WebOperationContext currentContext = WebOperationContext.Current;
            if (currentContext != null)
            {
               currentContext.OutgoingResponse.ContentType = mimeType;
               currentContext.OutgoingResponse.ContentLength = ms.Length;
            }

            return ms;
         }
      }
   }
   catch (Exception ex)
   {
      Log(string.Format("Load - Error:{1}{0}TempFile:{2}{0}Uri:{3}, PageNumber:{4}", Environment.NewLine, ex.Message, tempFile, uri, pageNumber));
      throw ex;
   }
   finally
   {
      if (File.Exists(tempFile))
      {
         try
         {
            File.Delete(tempFile);
         }
         catch { }
      }
   }
}

Here is my code:

Code:

public Stream LoadFromData(Stream streamData, int pageNumber, int resolution, string mimeType, int bitsPerPixel, int qualityFactor, int width, int height)
{
    // document data is not optional
    StreamReader reader = new StreamReader(streamData);
    string docData = reader.ReadToEnd();
    reader.Close();
    reader.Dispose();
    if (string.IsNullOrEmpty(docData))
        throw new ArgumentNullException("Document Data");

    if (pageNumber < 0)
        throw new ArgumentException("'pageNumber' must be a value greater than or equals to 0");

    // Default is page 1
    if (pageNumber == 0)
        pageNumber = 1;

    if (resolution < 0)
        throw new ArgumentException("'resolution' must be a value greater than or equals to 0");

    // Sanity check on other parameters
    if (qualityFactor < 0 || qualityFactor > 100)
        throw new ArgumentException("'qualityFactor' must be a value between 0 and 100");

    if (width < 0 || height < 0)
        throw new ArgumentException("'width' and 'height' must be value greater than or equal to 0");

    // Get the image format
    SaveImageFormat saveFormat = SaveImageFormat.GetFromMimeType(mimeType);

    // Use a temp file, much faster than calling Load/Info from a URI directly
    // In a production service, you might want to create a caching mechanism
    string tempFile = Path.GetTempFileName();
    try
    {
        // Create the file
        File.WriteAllBytes(tempFile, Convert.FromBase64String(docData));

        using (RasterCodecs codecs = new RasterCodecs())
        {
            ServiceHelper.InitCodecs(codecs, resolution);

            // Load the page
            using (RasterImage image = codecs.Load(tempFile, 0, CodecsLoadByteOrder.BgrOrGray, pageNumber, pageNumber))
            {
                // Resize it (will only resize if both width and height are not 0), will also take care of FAX images (with different resolution)
                ImageResizer.ResizeImage(image, width, height);

                // We need to find out the format, bits/pixel and quality factor
                // If the user gave as a format, use it
                if (saveFormat == null)
                {
                    // If the user did not give us a format, use PNG
                    saveFormat = new PngImageFormat();
                    mimeType = "image/png";
                }

                saveFormat.PrepareToSave(codecs, image, bitsPerPixel, qualityFactor);

                // Save it to a memory stream
                MemoryStream ms = new MemoryStream();
                codecs.Save(image, ms, saveFormat.ImageFormat, saveFormat.BitsPerPixel);
                ms.Position = 0;

                // Set the MIME type and Content-Type if there is a valid web context
                WebOperationContext currentContext = WebOperationContext.Current;
                if (currentContext != null)
                {
                    currentContext.OutgoingResponse.ContentType = mimeType;
                    currentContext.OutgoingResponse.ContentLength = ms.Length;
                }

                return ms;
            }
        }
    }
    catch (Exception ex)
    {
        Log(string.Format("LoadFromData - Error:{1}{0} PageNumber:{2}", Environment.NewLine, ex.Message, pageNumber));
        throw ex;
    }
    finally
    {
        if (File.Exists(tempFile))
        {
            try
            {
                File.Delete(tempFile);
            }
            catch { }
        }
    }
}

This code works, it gives me back a MemoryStream object similar to the original Load method that I can display as an image to the user.
However, I want to modify this code further to not use any temporary files. I've noticed that the codecs.Load() method is currently taking the path to the file but this method can also take a Stream object. I've tried using two different Stream objects for this method:
FileStream: I got file Stream to work as expected with no problems. However, using this Stream object still makes me use a temporary file to write my data to.

MemoryStream: This is the Stream object that I would like to use because I can simply write data to it without the use of a temporary file. However, I haven't gotten this Stream to work. When I use this Stream and call the method, I get back the following response from the server: {"Detail":null,"FaultType":"RasterException","Message":"Invalid file format"}
Here is my code that uses the MemoryStream instead of a temporary file:

Code:

public Stream LoadFromData(Stream streamData, int pageNumber, int resolution, string mimeType, int bitsPerPixel, int qualityFactor, int width, int height)
{
    // document data is not optional
    StreamReader reader = new StreamReader(streamData);
    string docData = reader.ReadToEnd();
    reader.Close();
    reader.Dispose();
    if (string.IsNullOrEmpty(docData))
        throw new ArgumentNullException("Document Data");

    if (pageNumber < 0)
        throw new ArgumentException("'pageNumber' must be a value greater than or equals to 0");

    // Default is page 1
    if (pageNumber == 0)
        pageNumber = 1;

    if (resolution < 0)
        throw new ArgumentException("'resolution' must be a value greater than or equals to 0");

    // Sanity check on other parameters
    if (qualityFactor < 0 || qualityFactor > 100)
        throw new ArgumentException("'qualityFactor' must be a value between 0 and 100");

    if (width < 0 || height < 0)
        throw new ArgumentException("'width' and 'height' must be value greater than or equal to 0");

    // Get the image format
    SaveImageFormat saveFormat = SaveImageFormat.GetFromMimeType(mimeType);

    // Use a temp file, much faster than calling Load/Info from a URI directly
    // In a production service, you might want to create a caching mechanism
    //string tempFile = Path.GetTempFileName();
    try
    {
        // Download the file
        MemoryStream docStream = new MemoryStream();
        StreamWriter writer = new StreamWriter(docStream);
        writer.Write(Convert.FromBase64String(docData));
        writer.Flush();
        docStream.Position = 0;

        using (RasterCodecs codecs = new RasterCodecs())
        {
            ServiceHelper.InitCodecs(codecs, resolution);

            // Load the page
            using (RasterImage image = codecs.Load(docStream, 0, CodecsLoadByteOrder.BgrOrGray, pageNumber, pageNumber))
            {
                // Resize it (will only resize if both width and height are not 0), will also take care of FAX images (with different resolution)
                ImageResizer.ResizeImage(image, width, height);

                // We need to find out the format, bits/pixel and quality factor
                // If the user gave as a format, use it
                if (saveFormat == null)
                {
                    // If the user did not give us a format, use PNG
                    saveFormat = new PngImageFormat();
                    mimeType = "image/png";
                }

                saveFormat.PrepareToSave(codecs, image, bitsPerPixel, qualityFactor);

                // Save it to a memory stream
                MemoryStream ms = new MemoryStream();
                codecs.Save(image, ms, saveFormat.ImageFormat, saveFormat.BitsPerPixel);
                ms.Position = 0;

                // Set the MIME type and Content-Type if there is a valid web context
                WebOperationContext currentContext = WebOperationContext.Current;
                if (currentContext != null)
                {
                    currentContext.OutgoingResponse.ContentType = mimeType;
                    currentContext.OutgoingResponse.ContentLength = ms.Length;
                }

                return ms;
            }
        }
    }
    catch (Exception ex)
    {
        Log(string.Format("LoadFromData - Error:{1}{0} PageNumber:{2}", Environment.NewLine, ex.Message, pageNumber));
        throw ex;
    }
}


I'm guessing it gives an Invalid File Format error because I'm not actually reading from a file.

In the original code, it mentions next to the creation of the temporary file "In a production service, you might want to create a caching mechanism". What is this referring to? Is it possible to write my code that doesn't use a temporary file? Is there a different Stream besides a FileStream that I can use?

Thanks for any help.

Edited by moderator Friday, May 12, 2017 10:00:12 PM(UTC)  | Reason: Not specified

 

Try the latest version of LEADTOOLS for free for 60 days by downloading the evaluation: https://www.leadtools.com/downloads

Wanna join the discussion? Login to your LEADTOOLS Support accountor Register a new forum account.

#2 Posted : Monday, May 15, 2017 4:01:22 PM(UTC)

Hadi  
Hadi

Groups: Manager, Tech Support, Administrators
Posts: 171

Was thanked: 5 time(s) in 5 post(s)

Hello,

Thank you for posting your question on the LEADTOOLS Technical Support Forums.

It seems that you issues is related to the StreamWriter. I created a sample application that sends a base64 encoded image in a stream and then I decoded it and loaded it with RasterCodecs and it works.

Try modifying your code to the following:

Code:
public Stream LoadFromData(Stream streamData, int pageNumber, int resolution, string mimeType, int bitsPerPixel, int qualityFactor, int width, int height)
{
    // document data is not optional
    StreamReader reader = new StreamReader(streamData);
    string docData = reader.ReadToEnd();
    reader.Close();
    reader.Dispose();

    if (string.IsNullOrEmpty(docData))
        throw new ArgumentNullException("Document Data");

    if (pageNumber < 0)
        throw new ArgumentException("'pageNumber' must be a value greater than or equals to 0");

    // Default is page 1
    if (pageNumber == 0)
        pageNumber = 1;

    if (resolution < 0)
        throw new ArgumentException("'resolution' must be a value greater than or equals to 0");

    // Sanity check on other parameters
    if (qualityFactor < 0 || qualityFactor > 100)
        throw new ArgumentException("'qualityFactor' must be a value between 0 and 100");

    if (width < 0 || height < 0)
        throw new ArgumentException("'width' and 'height' must be value greater than or equal to 0");

    // Get the image format
    SaveImageFormat saveFormat = SaveImageFormat.GetFromMimeType(mimeType);

    try
    {
       MemoryStream ms = new MemoryStream(Convert.FromBase64String(docData));

        using (RasterCodecs codecs = new RasterCodecs())
        {
            ServiceHelper.InitCodecs(codecs, resolution);

            // Load the page
            using (RasterImage image = codecs.Load(ms, 0, CodecsLoadByteOrder.BgrOrGray, pageNumber, pageNumber))
            {
                // Resize it (will only resize if both width and height are not 0), will also take care of FAX images (with different resolution)
                ImageResizer.ResizeImage(image, width, height);

                // We need to find out the format, bits/pixel and quality factor
                // If the user gave as a format, use it
                if (saveFormat == null)
                {
                    // If the user did not give us a format, use PNG
                    saveFormat = new PngImageFormat();
                    mimeType = "image/png";
                }

                saveFormat.PrepareToSave(codecs, image, bitsPerPixel, qualityFactor);

                // Save it to a memory stream
                MemoryStream ms = new MemoryStream();
                codecs.Save(image, ms, saveFormat.ImageFormat, saveFormat.BitsPerPixel);
                ms.Position = 0;

                // Set the MIME type and Content-Type if there is a valid web context
                WebOperationContext currentContext = WebOperationContext.Current;
                if (currentContext != null)
                {
                    currentContext.OutgoingResponse.ContentType = mimeType;
                    currentContext.OutgoingResponse.ContentLength = ms.Length;
                }

                return ms;
            }
        }
    }
    catch (Exception ex)
    {
        Log(string.Format("LoadFromData - Error:{1}{0} PageNumber:{2}", Environment.NewLine, ex.Message, pageNumber));
        throw ex;
    }
}
Hadi Chami
Developer Support Manager
LEAD Technologies, Inc.

LEAD Logo
 
#3 Posted : Tuesday, May 16, 2017 8:00:32 AM(UTC)
Toadfish

Groups: Registered
Posts: 11


Ah. Thank you for your help. That worked. Looks like I was overthinking the MemoryStream that read the docData.
 
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Powered by YAF.NET | YAF.NET © 2003-2017, Yet Another Forum.NET
This page was generated in 0.206 seconds.