Проверьте изображение из файла в C#

Измените последнее утверждение следующим образом:

EXEC('SELECT * FROM ' + @tablename)

Вот как я делаю свое действие в хранимой процедуре. Первый блок объявит переменную и задает имя таблицы на основе имени текущего года и месяца, в этом случае TEST_2012OCTOBER. Затем я проверяю, существует ли он в БД, и удалите, если это произойдет. Затем следующий блок будет использовать инструкцию SELECT INTO для создания таблицы и заполнить ее записями из другой таблицы параметрами.

--DECLARE TABLE NAME VARIABLE DYNAMICALLY
DECLARE @table_name varchar(max)
SET @table_name = 
    (SELECT 'TEST_'
            + DATENAME(YEAR,GETDATE())
            + UPPER(DATENAME(MONTH,GETDATE())) )

--DROP THE TABLE IF IT ALREADY EXISTS
IF EXISTS(SELECT name 
          FROM sysobjects 
          WHERE name = @table_name AND xtype = 'U')

BEGIN
    EXEC('drop table ' +  @table_name)
END

--CREATES TABLE FROM DYNAMIC VARIABLE AND INSERTS ROWS FROM ANOTHER TABLE
EXEC('SELECT * INTO ' + @table_name + ' FROM dbo.MASTER WHERE STATUS_CD = ''A''')
51
задан SemiColon 16 October 2008 в 23:33
поделиться

9 ответов

JPEG не имеет формального определения заголовка, но у них действительно есть небольшое количество метаданных, которые можно использовать.

  • Смещение 0 (Два байта): маркер SOI JPEG (шестнадцатеричное число FFD8)
  • Смещение 2 (Два байта): Ширина изображения в пикселях
  • Смещение 4 (Два байта): Высота изображения в пикселях
  • Смещение 6 (Байт): Количество компонентов (1 = шкала полутонов, 3 = RGB)

существует пара других вещей после этого, но те не важны.

можно открыть файл с помощью двоичного потока, и считать это исходные данные и удостовериться, что OffSet 0 0, и OffSet 6 или 1,2 или 3.

, Который, по крайней мере, дал бы Вам немного больше точности.

Или можно просто захватить исключение и идти дальше, но я думал, что Вы хотели проблему:)

22
ответ дан FlySwat 7 November 2019 в 19:45
поделиться

в случае, если вам нужно, чтобы данные считывались для других операций и/или для других типов файлов (например, PSD), то использование функции Image.FromStream не обязательно является хорошим идеалом.

-1
ответ дан 7 November 2019 в 09:45
поделиться

A метод, который также поддерживает Tiff и Jpeg

private bool IsValidImage(string filename)
{
    Stream imageStream = null;
    try
    {
        imageStream = new FileStream(filename, FileMode.Open);

        if (imageStream.Length > 0)
        {
            byte[] header = new byte[30]; // Change size if needed.
            string[] imageHeaders = new[]
            {
                "BM",       // BMP
                "GIF",      // GIF
                Encoding.ASCII.GetString(new byte[]{137, 80, 78, 71}),// PNG
                "MM\x00\x2a", // TIFF
                "II\x2a\x00" // TIFF
            };

            imageStream.Read(header, 0, header.Length);

            bool isImageHeader = imageHeaders.Count(str => Encoding.ASCII.GetString(header).StartsWith(str)) > 0;
            if (imageStream != null)
            {
                imageStream.Close();
                imageStream.Dispose();
                imageStream = null;
            }

            if (isImageHeader == false)
            {
                //Verify if is jpeg
                using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open)))
                {
                    UInt16 soi = br.ReadUInt16();  // Start of Image (SOI) marker (FFD8)
                    UInt16 jfif = br.ReadUInt16(); // JFIF marker

                    return soi == 0xd8ff && (jfif == 0xe0ff || jfif == 57855);
                }
            }

            return isImageHeader;
        }

        return false;
    }
    catch { return false; }
    finally
    {
        if (imageStream != null)
        {
            imageStream.Close();
            imageStream.Dispose();
        }
    }
}
3
ответ дан 7 November 2019 в 09:45
поделиться

Это должно помочь - вам не нужно читать необработанные байты из заголовка:

using(Image test = Image.FromFile(filePath))
{
    bool isJpeg = (test.RawFormat.Equals(ImageFormat.Jpeg));
}

Конечно, вы также должны перехватить OutOfMemoryException, что спасет вас если файл вообще не является изображением.

И в ImageFormat есть предустановленные элементы для всех других основных типов изображений, которые поддерживает GDI +.

Обратите внимание: вы должны использовать .Equals (), а не == для объектов ImageFormat (это не перечисление), потому что оператор == не перегружен для вызова метода Equals.

6
ответ дан 7 November 2019 в 09:45
поделиться

Ну, я шел вперед и кодировал ряд функций для решения проблемы. Это проверяет заголовок сначала, затем пытается загрузить изображение в блоке попытки/выгоды. Это только проверяет на GIF, BMP, JPG и файлы PNG. Можно легко добавить больше типов путем добавления заголовка к imageHeaders.

static bool IsValidImage(string filePath)
{
    return File.Exists(filePath) && IsValidImage(new FileStream(filePath, FileMode.Open, FileAccess.Read));
}

static bool IsValidImage(Stream imageStream)
{
    if(imageStream.Length > 0)
    {
        byte[] header = new byte[4]; // Change size if needed.
        string[] imageHeaders = new[]{
                "\xFF\xD8", // JPEG
                "BM",       // BMP
                "GIF",      // GIF
                Encoding.ASCII.GetString(new byte[]{137, 80, 78, 71})}; // PNG

        imageStream.Read(header, 0, header.Length);

        bool isImageHeader = imageHeaders.Count(str => Encoding.ASCII.GetString(header).StartsWith(str)) > 0;
        if (isImageHeader == true)
        {
            try
            {
                Image.FromStream(imageStream).Dispose();
                imageStream.Close();
                return true;
            }

            catch
            {

            }
        }
    }

    imageStream.Close();
    return false;
}
19
ответ дан SemiColon 7 November 2019 в 19:45
поделиться

Используя Windows Forms:

bool IsValidImage(string filename)
{
    try
    {
        using(Image newImage = Image.FromFile(filename))
        {}
    }
    catch (OutOfMemoryException ex)
    {
        //The file does not have a valid image format.
        //-or- GDI+ does not support the pixel format of the file

        return false;
    }
    return true;
}

Иначе, если Вы WPF использования, можно сделать следующее:

bool IsValidImage(string filename)
{
    try
    {
        using(BitmapImage newImage = new BitmapImage(filename))
        {}
    }
    catch(NotSupportedException)
    {
        // System.NotSupportedException:
        // No imaging component suitable to complete this operation was found.
        return false;
    }
    return true;
}

необходимо выпустить созданное изображение. Иначе при вызове этого функционального большого количества времен это бросило бы OutOfMemoryException, потому что система исчерпала ресурсы, и не потому что изображение является поврежденным получением неправильного результата, и если бы Вы удаляете изображения после этого шага, Вы потенциально удалили бы хорошие.

33
ответ дан Indy9000 7 November 2019 в 19:45
поделиться

Я создал бы метод как:

Image openImage(string filename);

, в котором я обрабатываю исключение. Если возвращенное значение является Пустым, существует недопустимое имя файла / тип.

0
ответ дан Enrico Murru 7 November 2019 в 19:45
поделиться

Вы могли считать первые несколько байтов Потока и сравнить их с волшебными байтами заголовка для JPEG.

0
ответ дан Quantenmechaniker 7 November 2019 в 19:45
поделиться

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

Это означает, что каждый формат файла, который Вы реализуете, должен будет иметь идентифицируемый заголовок...

JPEG: Первые 4 байта являются FF D8 FF E0 (на самом деле просто, первые два байта сделали бы это для не jfif jpeg, больше информации здесь ).

GIF: Первые 6 байтов являются или "GIF87a" или "GIF89a" (больше информации здесь )

PNG: Первые 8 байтов: 89 50 4E 47 0D 0A 1 А 0A (больше информации здесь )

TIFF: Первые 4 байта: II42 или MM42 (больше информации здесь )

и т.д.... можно найти заголовок/данные о формате для примерно любого графического формата, о котором Вы заботитесь и добавляете к вещам, которые это обрабатывает по мере необходимости. То, что это не сделает, говорят Вам, если файл является действительной версией того типа, но это даст Вам, подсказка об "изображении не отображает?". Это могло все еще быть поврежденным или неполным изображением, и таким образом отказать при открытии, таким образом, выгода попытки вокруг вызова.FromFile все еще необходима.

13
ответ дан Troy Howard 7 November 2019 в 19:45
поделиться