Сохранить растровое изображение в .Net сохраняет изображение в неправильном формате? - PullRequest
3 голосов
/ 28 августа 2009

У нас есть фрагмент кода, который сохраняет .Net System.Drawing.Bitmap в файл. Вызов Save указывает местоположение файла, а также формат изображения, который мы ожидаем сохранить данные изображения в формате Jpeg, поэтому код выглядит следующим образом:

public MediaFile IngestImage(System.Drawing.Bitmap imgSrc, string name){
     ... // left out because it is not relevant to this question
     imgSrc.Save(fullPath, System.Drawing.Imaging.ImageFormat.Jpeg);
     ... // left out because it is not relevant to this question
}

Почему-то время от времени этот метод генерирует изображения PNG в виде файлов .jpg. В большинстве случаев это не имеет большого значения, однако в другой части проекта есть проблемы с тем, что эти файлы не являются реальными JPEG-файлами (Windows Media Services).

Любая помощь приветствуется, кто-нибудь когда-либо видел это?

Примечание: полный путь - что-то вроде "\ servcer \ share \ file.jpg". Мы сохраняем JPG с расширением «JPG». Отсюда и проблема ... Позже мы создаем точки публикации на Windows Media Server для воспроизведения списка воспроизведения SMIL. Затем мы должны «объявить» файлы и форматы к точке публикации, когда точка публикации начинает воспроизведение, она ожидает файл Jpg, поскольку это расширение файла, а содержимое на самом деле PNG

Вот фактический код, создающий объект BitpMap, который передается в вышеуказанный метод ...

        public static Bitmap CreateBitmap(string text, int height, int width, Color foregroundColor, Color backgroundColor, string fontName, int fontSize, bool antialias)
    {
        // Initialize graphics
        Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            if (antialias)
            {
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.TextRenderingHint = TextRenderingHint.AntiAlias;
            }

            // Set colors
            SolidBrush fgBrush = new SolidBrush(foregroundColor);
            SolidBrush bgBrush = new SolidBrush(backgroundColor);

            // paint background
            RectangleF rectF = new RectangleF(0, 0, width, height);
            g.FillRectangle(bgBrush, rectF);

            // Load font
            FontFamily fontFamily = FontFamily.GenericSerif;
            Font font = new Font(fontFamily, fontSize, FontStyle.Regular, GraphicsUnit.Pixel);
            try
            {
                fontFamily = new FontFamily(fontName);
                font = new Font(fontFamily, fontSize, FontStyle.Regular, GraphicsUnit.Pixel);
            }
            catch { }

            // Set font direction & alignment
            StringFormat format = new StringFormat();
            format.Alignment = StringAlignment.Center;
            format.LineAlignment = StringAlignment.Center;

            // Finally, draw the text
            g.DrawString(text, font, fgBrush, rectF, format);

            return bmp;
        }
    }

Ответы [ 8 ]

3 голосов
/ 08 сентября 2009

Я бы подошел к этому:

  1. очистка вниз CreateBitmap(). Например, возникает ли проблема, если вы удалите все, кроме строки, которая вызывает new и строку return? Я бы предположил, что это будет, но это стоит проверить. Если по нечетной вероятности проблема исчезнет с этой модификацией, используйте бинарный поиск , чтобы проверить, можете ли вы отследить ее до определенной строки.

  2. , обертывающий вызов Save с try / catch, чтобы увидеть, если где-то молча съедается ExternalException Bitmap.Save() (унаследовано от Image.Save()) говорит следующее о ExternalException:

Изображение было сохранено с неправильной формат изображения.

-или-

Изображение было сохранено в том же файле он был создан из.

Возможно ли, что сбойные файлы уже существуют в fullPath в формате PNG с расширением .jpg?

2 голосов
/ 15 сентября 2009

Я также испытываю эту проблему в приложении обрезки. Исходный файл изображения представляет собой JPG. Я пробовал несколько разных типов ImageFormat, и во всех случаях сохраненный формат - PNG с расширением JPG. Затем Photoshop жалуется на «Недопустимый тип маркера JPEG». Если я переименую файл в .png, он прекрасно откроется в Photoshop.

Попытка сделать это с другим изображением, создает правильный формат JPG с расширением JPG.

Я подозреваю, что виноват формат исходного файла. Я опубликую свои выводы, когда эта проблема будет решена.

1 голос
/ 09 сентября 2009

Ну, я дал ему шанс и попытался воспроизвести проблему с кодом, приведенным выше. Вот примерно то, что я сделал:

    Random r = new Random();
    for (int i = 0; i < max; i++)
    {
        System.Diagnostics.Debugger.Break()
        int size = 1 + i;
        int width = 1 + i;
        SaveBitmap(@"C:\Projects\test.jpg", ImageFormat.Jpeg, "hello", size, width, Color.Black, Color.White, "Arial", size, true);
        SaveBitmap(@"C:\Projects\test.png", ImageFormat.Jpeg, "hello", size, width, Color.Black, Color.White, "Arial", size, true);
        SaveBitmap(@"C:\Projects\test.jpg", ImageFormat.Jpeg, "hello", size, width, Color.Black, Color.White, "Arial", size, false);
        SaveBitmap(@"C:\Projects\test.png", ImageFormat.Jpeg, "hello", size, width, Color.Black, Color.White, "Arial", size, false);
    }

    public static void SaveBitmap(string filename, ImageFormat format, string text, int height, int width, Color foregroundColor, Color backgroundColor, string fontName, int fontSize, bool antialias)
    {
        using (Image source = CreateBitmap(text, height, width, foregroundColor, backgroundColor, fontName, fontSize, antialias))
            source.Save(filename, format);

        using (Image imgLoaded = Bitmap.FromFile(filename))
        {
            if (imgLoaded.RawFormat.Guid != format.Guid)
                throw new InvalidOperationException();
        }
    }

Это выполняется без проблем, и проверка на то, что if (imgLoaded.RawFormat.Guid! = Format.Guid) никогда не прерывается в отладчике. Я предполагаю, что у вас есть немного больше кода, чем подпрограмма CreateBitmap, опубликованная выше.

Моя рекомендация:

Измените свой код и вставьте утверждение проверки в вышеупомянутый SaveBitmap () сразу после вашего вызова Image.Save (). Тогда иди разбей его и посмотри, как ты туда попал ...

0 голосов
/ 28 июня 2016

C # Win7 (64bit) VS 2010 Bitmap.Save ("wnd.bmp") сохраняется в формате png. MainWnd - это форма C #, которую я получаю и пытаюсь сохранить в файл в виде растрового изображения.

        Bitmap bmp = new Bitmap(MainWnd.ActiveForm.Width, MainWnd.ActiveForm.Height);
        Rectangle crec = MainWnd.ActiveForm.ClientRectangle;
        Rectangle r = this.ClientRectangle;
        MainWnd.ActiveForm.DrawToBitmap(bmp, r);
        bmp.Save("wnd.bmp");  // saves as PNG not BMP !!

00000000 89 50 4E 47 0D 0A 1A 0A - 00 00 00 0D 49 48 44 52 ‰ PNG ........ IHDR 00000010 00 00 04 0B 00 00 02 E6 - 08 06 00 00 00 24 30 1D ....... æ ..... $ 0. 00000020 D1 00 00 00 01 73 52 47 - 42 00 AE CE 1C E9 00 00 С .... sRGB.®Î.é ..

0 голосов
/ 11 февраля 2014

Вы можете попробовать это, чтобы сохранить файл

public bool ResizeImage(string OriginalFilepath, string NewFilepath)
    {
        Bitmap original = (Bitmap)Image.FromFile(OriginalFilepath);
        Bitmap resized = new Bitmap(original, new Size(width,height));
        resized.Save(NewFilepath.jpeg);

    }
0 голосов
/ 09 февраля 2010

Вы пытались установить ImageCodecInfo явно?

Dim enc = ImageCodecInfo.GetImageEncoders().ToList().Find(Function(e) e.MimeType = "image/png")
objBitMap.Save(stream, enc, params)
0 голосов
/ 14 сентября 2009

Возможно, это проблема с именем файла, которое вы или пользователь указываете. возможно, что если он заканчивается на .png, то jpegformat игнорируется и создается файл PNG.

0 голосов
/ 28 августа 2009

Похоже, ваш fullPath может сохранять файл с расширением png, и вы говорите imgSrc сжимать изображение с помощью сжатия Jpeg.

Я бы подтвердил, что расширение fullPath - это jpeg или jpg, а не png.

Вот MSDN DOC в Сохранить.

...