generic error in gdi+ decoding a valid jpeg - c#

I have a valid jpeg frame that is taken from a camera:
http://www.developerinabox.com/test.jpg
I'm loading this with the below (example) code:
using System.Net;
using System.Drawing;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
WebRequest req = WebRequest.Create("http://www.developerinabox.com/test.jpg");
req.Timeout = 5000;
WebResponse resp = null;
resp = req.GetResponse();
if (resp != null)
{
var s = resp.GetResponseStream();
if (s != null)
{
Image img = Image.FromStream(s); //<-- Error thrown here
}
}
}
}
}
In windows XP/Vista/7 this works fine.
In windows 8 it's failing with "generic error in gdi+" I've tried loading it via WPF with the same result.
I can display the image on my windows 8 PC in google chrome but not in IE. It will display in both on windows XP/Vista/7.
I can open it on my Windows 8 box in Fireworks but trying to open it in paint gives me:
"This is not a valid bitmap file, or its format is not currently supported."
Any ideas?

Actually, it is an invalid JPEG image but, as you can see, many applications can decode this image seamlessly. This JPEG image has a bogus SOS marker (sorry for the technical information), this Scan header (SOS) says that this image has 1 color component but the Frame header (SOF, which appears before the SOS in the JPEG file structure) claims that it's a 3 components image.
So the Scan header has less information than required but the missing information can be replaced with default values and the JPEG image should be decoded with no issues, which is exactly what is happening. The missing information are the Huffman table indices and default sets of these indices can be assumed based on the JPEG coding type (sequential, progressive or lossless).
Well, it seems that Win8 is stricter when it comes to JPEG decoding. If you are curious you can take a look to this code I uploaded for another JPEG related issue (it's coded in VB.NET) and you can debug it to know where the problem is (you should check JPEG specifications as well).
EDIT: It was a valid JPEG image after all
This JPEG is a baseline multi-scan sequential image (similar to a planar image), not to be confused with a progressive image (which is similar to an interlaced image). So this JPEG has a smaller Scan header because the image is decoded one component at a time. Thus, this file has 3 non-contiguous Scan headers (SOS for 1st component, compressed data, SOS for 2nd component, compressed data,...), and each scan header has information for a single component.
Finally, if the problem was an incomplete or bogus scan header there would be a workaround (you could fix a bogus SOS header) but this is not the case. So you could make a request to the MS guys asking for support for multi-scan sequential JPEG images on Win8 ;-) or use some third-party JPEG decoding library.

Related

Problem with saving PNM image on Windows in my app

I am creating a photo editing app for my c# project. I need to support different image formats, but to begin with, I chose a very simple format - PNM. At the moment, I can open PNM images and change the color scheme, but strange things happen when saving. When saving the image on macOS, everything works fine, but after trying a similar action on Windows, I got a strange effect, the colors were read with a shift of 1 byte with each new opening after saving.
Here is an example of an image:
example image
That’s what is happening after loading and re-opening it on Windows:
damaged image
It is logical to assume that the problem is in the methods of saving the image. I first write the entire file header to the stream, and then write the color bytes one by one.
I can't figure out what exactly the problem is, because when debugging, the array of bytes being written contained nothing extra. Opening the image in the notepad before and after saving, I did not find any visible changes.
Here is my implementation of saving in a file:
public void SaveTo(Stream stream)
{
_filter.WriteHeader(stream, _image);
foreach (var (x, y) in _enumerationStrategy.Enumerate(Width, Height))
{
var triplet = _image[x, y];
_filter.Write(stream, triplet, _converterProvider.Converter);
}
}
public void WriteHeader(Stream stream, IBitmapImage image)
{
var builder = new StringBuilder();
builder.AppendLine("P6");
builder.AppendLine($"{image.Width} {image.Height}");
builder.AppendLine("255");
var header = builder.ToString();
var headerBytes = Encoding.UTF8.GetBytes(header);
stream.Write(headerBytes, 0, headerBytes.Length);
}
I tried to create a header of image without a string builder, and I tried to write the header to the stream in different ways. Trying different encodings to convert bytes didn't work out too. The effect is the same...
I guess your issue is caused by inconsistent line endings between operating systems. When you use AppendLine it adds a \n character after your string which is translated to binary differently, depending on the OS you running.
I suggest you to write a line ending directly like so:
builder.Append((char)10);

Poor image quality when converting word docs with evo pdf

I use the WordToPdfConverter from evo to convert a Word document to a PDF. The Word document, which is in RTF format, contains images such as a QR code.
Unfortunately, the image quality in the resulting PDF is very poor (hence the QR code won't be readable). Even if I disable image compression or set it to the lowest level (=> best quality), the resulting image has a very poor quality.
Is there any other way to control the image quality? Or is there a way to tell evo's WordToPdfConverter not to use JPG as the resulting image format but to stuck with the source format (e.g. PNG)?
var pdfConverter = new WordToPdfConverter();
// Set Pdf image options
pdfConverter.PdfDocumentOptions.JpegCompressionEnabled = false;
pdfConverter.PdfDocumentOptions.JpegCompressionLevel = 0;
var filename = #"C:\temp\evo\TestWordDoc.rtf";
pdfConverter.ConvertWordFileToFile(filename, Path.Combine(Path.GetDirectoryName(filename), $"{Path.GetFileNameWithoutExtension(filename)}_{DateTime.Now:yyyyMMddHHmmss}.pdf"));
Since RTF is a text format, you should convert it to PDF without having to do any image compression as that will take longer to process and will result in a larger output file + you might have issues with the image quality from embedded images.
I created a sample RTF file (test.rtf) that contains a QR code as you described:
I then took the RTF and ran it through the Document Converter from the Leadtools.Document.sdk Nuget. Just as a disclaimer: I am associated with this library.
This document converter preserves the text and parses the images as-is from the source document, then outputs it to PDF.
You can download the output PDF from here: test.pdf
Here is some sample code:
using (var documentConverter = new DocumentConverter())
{
var filename = #"C:\temp\evo\TestWordDoc.rtf";
var document = DocumentFactory.LoadFromStream(filename, new LoadDocumentOptions());
var jobData = DocumentConverterJobs.CreateJobData(filename, Path.Combine(Path.GetDirectoryName(filename), $"{Path.GetFileNameWithoutExtension(filename)}_{DateTime.Now:yyyyMMddHHmmss}.pdf"), DocumentFormat.Pdf);
var job = documentConverter.Jobs.CreateJob(jobData);
documentConverter.Jobs.RunJob(job);
}
I am failing to see why people have issues with QR codes such as this one which is just a template (I could not download any of the older samples above for comparison.)
 
 
It is a PNG demo template file designed to be scanned from up to 4 feet away (e.g. a poster) but it could be for production, much smaller i.e. lower scale for page scanning.
I drop the RTF on the WordPad print to pdf shortcut and get the pdf shown in the viewer almost instantly.
There is some natural degradation using RTF PNG and an aliased viewer, but the key is maintaining natural scales. Every thing you need is native as supplied with windows.
MSPaint, WordPad, CMD printing I could have sent preview to the PDFium viewer in Edge.

.net Compact Framework 2.0 - OutOfMemory Exception When downloading an image

Im creating software for a Symbol MC75A using c# .net CF 2.0. We scan a barcode and it returns stock information but i am trying to add a feature that gets an image from a url. Each scan refreshes the screen with new data from database and also gets the image from the new url. It scans a few barcodes and returns maybe 4/5 images without issue then all of a sudden a OutOfMemoryException occurs. The code im using to Get Image is:
public Bitmap GetImage(string URL)
{
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(URL);
myRequest.Method = "GET";
myRequest.AllowWriteStreamBuffering = false;
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(myResponse.GetResponseStream());
myResponse.Close();
return bmp;
}
Called by:
pbImage.Image = GetImage(ProductImage);
pbImage.SizeMode = PictureBoxSizeMode.StretchImage;
I have tried to dispose of image before each new GET with pbImage.Image.Dispose() but still getting the same exception. The image sizes are between 100KB and 550KB. Whether it makes a difference the images sizes are always over 1000px each side.
Am i missing the correct way of disposing before re-getting or is it somehow caching all these images which then creates an outofMemory exception?
I have found my solution herer:
OutOfMemoryException loading big image to Bitmap object with the Compact Framework
It seems it is the system.drawing when decompressing the 2000px image it is creating an uncompressed image giving a larger size on the memory hense the exception. The solution shows a way to obtain a thumbnail of the image rather than the whole image.
Thanks for your help again.
Just incase someone has access to the image location. A better work around for me was to creat a webpage named resize.aspx and have the picture box populate from the page with the image filename as a parameter. Now that page (being on the server in the same location as the images) was able to resize the image and return a small 300x300px image. Seemed to be the best solution i could think of. This can also work for images at any url if you pass the full url of the image into another page and that page returns the required thumbnail.

Change dicom Transfer Syntax showing no registered codec using mDCM

I am having issue while changing the Transfer Syntax.
I am using mDCM library and I have added the Dicom.Codec.dll to the project as well.
The compressed files are having 0002,0010,Transfer Syntax UID=1.2.840.10008.1.2.4.90 (JPEG 2000 Image Compression (Lossless Only)).
Error: DicomCodecException was caught. No registered codec for transfer syntax!
My code:
string file = "C:\\Dicom\\1001.dcm";
string output = "C:\\Dicom\\Decompressed\\1001.dcm";
DicomFileFormat ff = new DicomFileFormat();
ff.Load(file, Dicom.DicomReadOptions.Default);
ff.ChangeTransferSytnax(DicomTransferSyntax.ExplicitVRLittleEndian, null); // Error here. No registered codec for transfer syntax!.
Dicom.Imaging.DicomImage im = new Dicom.Imaging.DicomImage(ff.Dataset);
System.Drawing.Image i = im.Render();
i.Save(output);
Another thing that I noted is that the tag 7FE0,0010,Pixel Data=0. For other dicom files, Pixel data tag is having values greater than 0.
The file is not opening in my other dicom viewers (ezDICOM, DicomWorks, IrfanView etc.) as well. So, I thought the file is corrupted. But, then the client gave us an application(.exe) which decompresses the file.
After decompression, all my viewers was showing the image properly.
Decompressed files was having 7FE0,0010,Pixel Data=131072.
As the error mentioned, I was not registering the codec.
This line registered the codec.
Dicom.Codec.Jpeg2000.DcmJpeg2000Codec.Register();

How do i URL rewrite an image properly? C# ASP.NET

I tried several ways to URL rewrite. The first way the image mime was clobbered and was consider an octet stream which didnt allow me to view the image in a browser (unless it was using img src). The 2nd way i wasnt convince it worked. Firefox displayed the img but said the length was 0 (i think it only worked bc it was in my cache).
How do i properly rewrite the image /abc/id/title.png to the internal location /static/user/name/id.png
In ASP.NET I might do something like this:
Response.Clear();
Response.ContentType = profile.AvatarMimeType;
Response.BinaryWrite(profile.Avatar.ToArray());
Where profile.AvatarMimeType is an appropriate mime type for a gif, jpeg, or png.
And where profile.Avatar.ToArray() is a binary content from the db sent out as an array of data!

Categories