tags:

views:

2813

answers:

2

I have some code that scales the images users upload. It works perfectly in most situations, but sometimes they upload jpegs that contain cmyk information.

After googling a bit, it seems like jpegs with cmyk values isn't valid, but since they work in windows, the users assume it's a problem with my application, so I need to be able to handle those situations. The questions:

How do I detect if the jpeg contains cmyk information?(it would allow me to inform the user why it doesn't work).

How can I convert it to a normal jpeg?

A: 

Jpeg is an standard which support any number of planes encoded (they are compressed independently of each other) inside a bitstream, so a jpeg with a cmyk profile is perfectly valid. Most jpeg files are encoded using a jfif container (http://en.wikipedia.org/wiki/JFIF) which originally only supported grayscale images, YCbCr, or sRGB, but it is extensible and Adobe have a custom tag to support cmyk profiles.

Take a look at this link for a workaround http://www.jroller.com/greenhorn/entry/adobe_photoshop_and_jpeg_cmyk, it is in java but you can port it easily to c#.

Ismael
CMYK might be perfectly valid, however sometimes IE doesn't show the image properly.
davethegr8
I fail to see how this is related to the question, but it seems to be an issue/limitation of IE.
Ismael
Well, Firefox 3 does display the images, but with the "wrong" colors. IE6 simply gives the box with a red X. You decide which is better.
Randy Stegbauer
I still fail to see how this is related to the question here, the question is 'How to detect a CMYK jpeg file'. The jpeg standard is designed to cover a wide range of still pictures, 16 bits, multiple planes, lossless encoding, etc.The most common container is jfif, and the most common options is to store in YCbCr format, that's the format most programs support.Support other color spaces is a desirable feature, but I don't think this is the primary concern of web browser developers.
Ismael
+1  A: 

In ASP.NET you can determine if a JPG is saved using the CMYK profile with the help of the System.Drawing.Imaging.ImageFlags enumeration,

http://msdn.microsoft.com/en-us/library/system.drawing.imaging.imageflags(VS.80).aspx

Let's say you have a basic aspx page where a user uploads a file and you need to tell,

1) is it a jpg? 2) is it using RGB?

Your aspx might be along the lines of,

<form id="form1" runat="server" enctype="multipart/form-data">
<asp:FileUpload ID="myUpload" runat="server" />
<asp:Button ID="submitButton" runat="server" Text="Submit" OnClick="Click_submitButton" />      
<br /><br />     
<asp:Literal ID="feedback" runat="server" />
</form>

and then for your code behind (C#) you can do,

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void Click_submitButton(object sender, EventArgs e)
    {
        if (myUpload.HasFile && isUploadAJpeg(myUpload.PostedFile))
        {
            System.Drawing.Bitmap uploadedImage = new System.Drawing.Bitmap(myUpload.PostedFile.InputStream);
            if (isFileACMYKJpeg(uploadedImage))
            {
                feedback.Text = "The file is a CYMK jpg";
            }
            else
            {
                feedback.Text = "This is a RGB jpg";
                //it is a rgb jpg --> do something with it
            }
        }
        else
        {
            feedback.Text = "You did not upload a jpg";
        }
    }

    protected bool isUploadAJpeg(HttpPostedFile someFile)
    {
        if (someFile.ContentType == "image/jpg" || someFile.ContentType == "image/jpeg" || someFile.ContentType == "image/pjpeg")
        {
            return true;
        }
        return false;
    }

    protected bool isFileACMYKJpeg(System.Drawing.Image someImage)
    {
        System.Drawing.Imaging.ImageFlags flagValues = (System.Drawing.Imaging.ImageFlags)Enum.Parse(typeof(System.Drawing.Imaging.ImageFlags), someImage.Flags.ToString());
        if (flagValues.ToString().ToLower().IndexOf("ycck") == -1)
        {
            return false;
        }
        return true;
    }
}

Hope that helps!

Anjisan