Сайт для программистов
Показаны сообщения с ярлыком Разное. Показать все сообщения
Показаны сообщения с ярлыком Разное. Показать все сообщения

вторник, 9 февраля 2010 г.

Получить информацию о BMP-файле

Если вам приходится работать с графическими файлами, то, возможно, у вас появится задача получить дополнительную информацию - узнать размеры файла, глубину цвета и т.п. Безусловно, вы можете загрузить картинку из файла на форму или подходящий элемент управления (PictureBox) и получить требуемую информацию. Но, предположим, ваш проект предназначен только для сбора информации о файлах. В этом случае загружать 10-мегапиксельный рисунок в форму неоправданно - получается слишком большой расход памяти. Есть другой способ получения нужной информации. О нем и пойдет речь сегодня.

Графические файлы являются бинарными файлами с определенной структурой. Так вот, в файле уже содержатся необходимые нам данные. Наша задача - уметь извлечь данную информацию. Не будем углубляться в технические детали форматов графических файлов. Достаточно знать, что, например, ширина картинки записана всегда в строго определенном месте от начала файла. Поэтому, нам нужно только открыть файл для считывания байтов, отсчитать нужное количество байт и получить необходимое число. Кстати, по такому принципу устроены не только графические файлы, но и многие другие файлы, например, музыкальные.

Но, вернемся к файлам BMP. В начале каждого файла в формате BMP идет так называемый заголовок файла. В документации он описывается структурой BITMAPFILEHEADER, которая имеет общую длину 14 байтов: три UInt16 и два UInt32. Нас не интересует данный заголовок, поэтому вы его должны просто проигнорировать. Таким образом в коде нам нужно открыть файл и пропустить 14 байт:

reader.ReadBytes(14);

Обратите внимание, что функцию sizeof в данном случае использовать нельзя. Функция sizeof работает только с неуправляемыми ресурсами. После структуры BITMAPFILEHEADER идет структура BITMAPINFOHEADER. Именно, в этой структуре хранится необходимая информация, которую необходимо извлечь (кстати, описание структуры можно найти в справочнике по функциям Windows API для Visual Basic). Вот как будет выглядеть код извлечения информации из файла:

private void ShowBMPInfo(String file)
{
FileStream fs = new FileStream(file, FileMode.Open);
BinaryReader reader = new BinaryReader(fs);

// Пропускаем заголовок файла (14 байтов)
reader.ReadBytes(14);

// Пропускаем размер структуры BITMAPINFOHEADER
reader.ReadUInt32();

// Получаем ширину и высоту
int width = reader.ReadInt32();
int height = reader.ReadInt32();

// опять пропускаем часть байтов
reader.ReadInt16();

// Получаем глубину цвета (битов на пиксел)
Int16 bitsPerPixel = reader.ReadInt16();

// Освобождаем ресурсы
reader.Close();
fs.Close();

// Выводим информацию
MessageBox.Show(width + " x " + height + " x " + bitsPerPixel);
}

private void button1_Click(object sender, EventArgs e)
{
ShowBMPInfo(textBox1.Text); // подставляем путь к файлу
}

Тут есть одна тонкость. Пропускаемые в коде байты на самом деле все равно считываются. Чтобы действительно перепрыгнуть через заданное число байтов, вы должны использовать методы и свойства объекта потока (stream object). Например, получить текущий поток через свойство BaseStream и пропустить первые 14 байтов можно так:


reader.BaseStream.Seek(14, SeekOrigin.Begin);

Кроме того, можно передвинуть внутренний указатель на заданное смещение от конца потока или от текущей позиции. Вот как пропустить короткое целое (2 байта):


reader.BaseStream.Seek(2, SeekOrigin.Current);

С учетом этих особенностей я написал второй вариант извлечения данных из файла.


private void ShowBMPInfo2(String file)
{
FileStream fs = new FileStream(file, FileMode.Open);
BinaryReader reader = new BinaryReader(fs);

// Пропускаем заголовок файла (14 байтов) без считывания
reader.BaseStream.Seek(14, SeekOrigin.Begin);

// Пропускаем размер структуры без считывания
reader.BaseStream.Seek(4, SeekOrigin.Current);

// Получаем ширину и высоту
int width = reader.ReadInt32();
int height = reader.ReadInt32();

// Пропускаем
reader.ReadInt16();

// Получаем глубину цвета (битов на пиксел)
Int16 bitsPerPixel = reader.ReadInt16();

reader.Close();
fs.Close();

// Выводим информацию
MessageBox.Show(width + " x " + height + " x " + bitsPerPixel * planes);
}

private void button2_Click(object sender, EventArgs e)
{
ShowBMPInfo2(textBox1.Text);
}

Толчком к написаню данного топика послужила статья из журнала MSDN за август 2002 года. Там же вы можете найти код для Visual Basic.NET.

Данный совет также будет помещен в раздел Графика на моем сайте.

Удачного вам программирования!

воскресенье, 26 апреля 2009 г.

ToTitleCase

В .NET Framework есть такой интересный метод как ToTitleCase, когда в заданной строке все первые буквы слов становятся большими, а остальные - маленькими. В MSDN можно найти описание и пример использования этого метода. Прочитав, вы узнаете, что у метода есть одна особенность: если все буквы в слове большие, то с этим словом ничего не происходит. Например, это удобно, когда встречаются такие слова как СССР, МГУ, ЗАГС и т.п. Но тем не менее, иногда, хочется обойти это ограничение. Что для этого нужно сделать. Правильно, сначала перевести все слова в нижний регистр, а затем вызвать метод ToTitleCase.


Именно так поступил программист Jan Schreuder, написав функции-обертки для этого метода (блог http://bloggingabout.net/)



private string ToTitleCase(string text, System.Globalization.CultureInfo culture, bool forceCasing)
{
if (forceCasing)
{
return culture.TextInfo.ToTitleCase(text.ToLower());
}
return culture.TextInfo.ToTitleCase(text);
}

private string ToTitleCase(string text)
{
return ToTitleCase(text, System.Threading.Thread.CurrentThread.CurrentCulture, false);
}

private string ToTitleCase(string text, bool forceCasing)
{
return ToTitleCase(text, System.Threading.Thread.CurrentThread.CurrentCulture, forceCasing);
}

private string ToTitleCase(string text, System.Globalization.CultureInfo culture)
{
return ToTitleCase(text, culture, false);
}

//Вызываем какую-нибудь функцию
label1.Text = ToTitleCase(textBox1.Text, true);


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


Вот как будут выглядеть строки после вызова всех вариантов функций.



change this to title case => Change This To Title Case
chanGe This to TITLE case => Change This To TITLE Case
ChanGe This to TITLE case => Change This To TITLE Case
ChanGe This to TITLE case => Change This To Title Case

Возможно, пример покажется не самым полезным в вашей практике, ну, а вдруг пригодится.

суббота, 27 декабря 2008 г.

Что общего между Microsoft и пивом?

Ответ: пивной бокал. Не прекращается поток подарков от Microsoft. На следующий день после первого подарка (см. предыдущий пост) меня снова побеспокоила служба DHL. На этот раз компания Microsoft подарила мне пивной бокал.

Если вы помните, я предлагал вам участвовать в конкурсе, в котором можно было выиграть призы. Я тоже участвовал и мне удалось стать обладателем приза. Спустя несколько месяцев награда нашла героя.

Кстати, компания приготовила еще один подарок - можно бесплатно скачать электронную версию книги по Silverlight. Ссылку не даю, ищите сами.

С наступающим Новым годом и счастливого вам программирования!

четверг, 25 декабря 2008 г.

Новогодние подарки от Microsoft

Сегодня служба DHL доставила в мой дом большую посылку (41х34х27 см). Оказалось это подарок от Microsoft. Некоторое время назад по интернету прошел слух, что компания подарит набор из 8 книг по программированию всем, кто подпишется на их рассылку. Не особо веря в чудо, я все-же подписался. И вот, накануне Нового года Microsoft решила немного побыть Дедом Морозом и стала рассылать подарки.


В коробке под толстым-толстым слоем упаковочной пленки (такая с кнопочками, которые так любят давить некоторые особы для успокоения нервов) оказалась еще одна красивая коробка Боекомплект ИТ-профессионала и разработчика, а также DVD-диск с Библиотекой MSDN и Visual Studio 2008 Express. Перечислять все книги я не буду. Но все они очень интересные.
С Рождеством, вас, Microsoft!
И большое спасибо за подарки!

понедельник, 1 декабря 2008 г.

PrintScreen, Codin4Fun и справочник по Visual Studio

Здравствуйте!
Наступило 1 декабря, а на улицах Москвы нет снега. Перейдем к новостям. Сегодня перечитывал журнал MSDN Magazine за ноябрь 2005 года и наткнулся на статью, как отключить клавишу PrintScreen, чтобы пользователь не мог скопировать снимок экрана в буфер. Автор статьи рассказывает о том, что в принципе, помешать чужой программе получить снимок экрана невозможно. Но, тем не менее, если вам все-таки нужно отключить клавишу PrintScreen, то воспользуйтесь функцией Windows API RegisterHotKey с константами IDHOT_SNAPDESKTOP и IDHOT_SNAPWINDOW. Далее в статье приводится пример на C++. Так как в моем справочнике по функциям Windows API уже было описание этой функции, то я решил написать тестовое приложение, чтобы проверить, как это все работает. Результат своих опытов я помещу в справочник в виде отдельной статьи, которая будет доступна зарегистрированным пользователям через несколько месяцев. Остальных приглашаю попробовать самостоятельно написать аналогичную программу.
Также в разделе справочники появился еще один справочник по Visual Studio. В последнее время пополнение справочника идет за счет советов Сары Форд, которые доступны с русскоязычного блога. А сегодня появилась еще одна хорошая новость - был запущен русский Codin4Fun по адресу http://blogs.msdn.com/rucoding4fun. К сожалению, на сайте появятся переводы постов, начиная с февраля 2008 года. Более ранние статьи (а среди них есть очень интересные) останутся без перевода. Если у вас есть желание перевести какие-нибудь старые статьи, то присылайте мне по адресу rusproject@mail.ru. В разделе Статьи я уже опубликовал несколько материалов оттуда.
Присоединяйтесь!
Всем удачного программирования!

понедельник, 24 ноября 2008 г.

CoCreateGuid, "Русалка" и блондинка

Начну свою запись в блоге с функции Windows API CoCreateGuid. Если вы раньше использовали эту функцию в .NET Compact Framework 1.1, то можете отказаться от нее, так как в CF2.0 и выше поддерживается метод Guid.NewGuid. Я убрал описание этой функции из справочника по функциям Windows API и поместил ее на страницу устаревших функций.
Кстати, если вы программируете для мобильных устройств, то обратите внимание, что вышли новые версии эмуляторов под Windows Mobile 6.1. (ссылки ищите здесь).
Переходим к Русалке. Недавно я рассказывал о песне в исполнении певицы Массква про телефон за тысячу евро. Недавно по 1 каналу показали этот фильм. Я не мог пропустить это событие и посмотрел картину. Мне фильм понравился, и песня нормально слушается. А как вам?
И, напоследок, расскажу о встрече с блондинкой. Шел я недавно в центре Москвы по Кривоколенному переулку. Навстречу мне идет молодая блондика и обращается за помощью. Ей нужен был дом 9, а мы стояли как раз между домами 8 и 10. Она мне и говорит: "Вы случайно не местный? Не подскажете, где дом 9, вот дом 8, а за ним сразу дом 10". Я немного растерялся, на миг потерял дар речи. Потом все-таки собрался, показал рукой на другую сторону переулка и сказал, что нечетные номера домов находятся на другой стороне. Она так удивилась...
Удачи вам, блондинки!

четверг, 11 сентября 2008 г.

Microsoft готова обменять твои знания на призы

Microsoft запустила любопытную акцию - вам необходимо пройти тест из пяти вопросов. Если вы пройдете тест, то у вас есть шанс выиграть какой-нибудь приз. Вопросы совсем не сложные, поэтому попробовать свои силы может даже программист-любитель. На данный момент существует более 50 тестов на самые разные темы. Ссылку на сайт с викториной я разместил на своей главной странице. Поэтому заходим на нее, кликаем на кнопочке или ссылке и участвуем.
Счастливого вам прохождения тестов!

четверг, 31 июля 2008 г.

11 правил Билла Гейтса

Попался мне на глаза еженедельник Upgrade. Там наткнулся на интересную статью. Якобы Билл Гейтся, выступая перед американскими школьниками, привел 11 правил, которым не учат в школе. Неизвестно, насколько достоверна эта информация, но правила представляют определенный интерес. Эти правила элементарно находятся по поисковому запросу. Поэтому, я не стал перепечатывать правила из журнала, а скопировал из первого попавшего источника в сети. Литературный перевод правил на некоторых сайтах различается, но общий смысл одинаков.
Правило 1: Жизнь не справедлива – привыкайте.
Правило 2: Общество совершенно не волнует Ваша САМООЦЕНКА. От вас ждут ДОСТИЖЕНИЙ прежде всего.
Правило 3: Вы НЕ БУДЕТЕ зарабатывать $60,000 в год сразу по окончании школы. Вы не станете вице-президентом с личным водителем, пока вы не заработаете на то и другое.
Правило 4: Если вы думаете, что учитель слишком суров по отношению к вам, - это еще цветочки. Подождите, пока у вас появится босс.Правило
5: Жарить гамбургеры - ниже вашего достоинства? Ваши дедушки и бабушки считали совсем по-другому. Для них жарить гамбургеры было возможностью зацепиться в этой жизни.
Правило 6: Если у вас что-то не вышло, это не вина ваших родителей, так что не надо хныкать, УЧИТЕСЬ на своих ошибках.
Правило 7: Родители не всегда были такие скучные, как вам сейчас кажется. Может быть постоянная забота о вас сделала их такими? Они вас кормят, одевают, постоянно слушают какие вы замечательные. Так что прежде чем критиковать поколение своих родителей, начните с себя.
Правило 8: Быть может в вашей школе не корректно открыто называть неудачника неудачником и в вашей школе уже не осталось неудачников, но не в жизни. В некоторых школах уже не возможно остаться на второй год, потому что вам дается СТОЛЬКО попыток СДАТЬ экзамены, сколько необходимо для перевода в другой класс. В жизни все СОВСЕМ по-другому.
Правило 9: Жизнь не делится на семестры. У вас не будет летних каникул, и ваш работодатель не будет помогать вам НАЙТИ СЕБЯ. Вам придется делать это самим в свое свободное время.
Правило 10: В телевизоре не показывают НАСТОЯЩУЮ жизнь. В реальной жизни не получится весь день сидеть в кафе и болтать с друзьями.
Правило 11: Поласковее с «ботаниками». Один из них может оказаться вашим боссом после окончания школы.
Удачи вам в этой жизни! (это от меня)