Консультация № 182373
04.03.2011, 11:22
58.87 руб.
0 15 1
Здраствуйте уважаемые эксперты!
Столкнулся с проблемой. Помогите, пожалуйста. Необходимо в Visual Studio C++ 2008 реализовать интерфейс программы, которая преобразует картинку в формате bmp из RGB в YIQ и обратно. Большое спасибо за помощь!

Обсуждение

давно
Профессор
230118
3054
04.03.2011, 11:25
общий
А программа самого преобразования есть?
Неизвестный
04.03.2011, 11:29
общий
04.03.2011, 13:00
это ответ
Здравствуйте, Mangoost!

Преобразования между RGB <-> YIQ выполняются следующим образом:

Y = 0.299*R + 0.587*G + 0.114*B
I = 0.596*R - 0.274*G - 0.322*B
Q = 0.212*R - 0.523*G + 0.311*B

и обратно:
R = 1.0*Y + 0.956*I + 0.621*Q
G = 1.0*Y - 0.272*I - 0.647*Q
B = 1.0*Y - 1.105*I + 1.702*Q

Код для чтения BMP-файла:


Код:
struct TBMPHeader{
//заголовок файла
short Type;
//сигнатура BM 0x4D42
long Size;
//размер файла в байтах 3*H*W+54
long Reserved;
//зарезервировано 0
long OffsetBits;
//смещение изображения от начала файла 54
//информационный заголовок
long SizeH;
//размер заголовка 40 информационного заголовка
long Width;
//ширина изображения
long Height;
//высота изображения
short Planes;
//число плоскостей 1
short BitCount;
//глубина цвета, бит на точку 24
long Compression;
//тип еомпрессии(0 - несжатое изображение)
long SizeImage;
//разиер изображения, байт 3*W*H
long XPelsPerMeter; //горизонтальное разрешение, точка на метр 0
long YPelsPerMeter; //вертикальное разрешение, точка на метр 0
long ColorUsed; //число используемых цветов 0
long ColorImportant;//число основных цветов 0
};

struct TBGR {
unsigned char b;
unsigned char g;
unsigned char r;
};

LoadBMPFile(char *fname){
TBMPHeader BMPHeader;
FILE *f;
if ((f = fopen(fname,"rb")) == NULL){
cout<<"Ошибка открытия файла";
return;
}
fread(&BMPHeader,sizeof(TBMPHeader),1,f);
TBGR *inBGR = new TBGR[BMPHeader.Width]; //массив указателей на слова
while(!feof(f)){
fread(inBGR,3*BMPHeader.Width,1,f);
// Здесь делаете преобразования и тут же записываете в новый файл или используете по своему усмотрению.
}
fclose(f);
}
Неизвестный
04.03.2011, 11:29
общий
Цитата: Асмик Гаряка
А программа самого преобразования есть?

Увы, нет!
Неизвестный
04.03.2011, 11:33
общий
Y = 0.299*R + 0.587*G + 0.114*B I = 0.596*R - 0.274*G - 0.322*B Q = 0.212*R - 0.523*G + 0.311*B и обратно: R = 1.0*Y + 0.956*I + 0.621*Q G = 1.0*Y - 0.272*I - 0.647*Q B = 1.0*Y - 1.105*I + 1.702*Q

Эти формулы мне известны.Интересует практическая часть... :)
давно
Профессор
230118
3054
04.03.2011, 11:35
общий
То есть нужна форма, в которой можно выбрать файл, его показать и т.д.?
Неизвестный
04.03.2011, 11:36
общий
А в чем возникает сложность?
Формат BMP содержит для каждого пикселя составляющие R, G, B.
Просто последовательно для каждой точки пересчитываете в Y, I, Q. Далее используете как Вам требуется.
Неизвестный
04.03.2011, 11:37
общий
Адресаты:
Вид картинки не изменится при пересчете компонент. Просто для каждой точки будут получены новые составляющие формата NTSC.
давно
Профессор
230118
3054
04.03.2011, 11:42
общий
Автор вопроса употребил слово интерфейс. Видимо, не случайно.
Неизвестный
04.03.2011, 11:42
общий
Цитата: 351298
А в чем возникает сложность?

Главная сложность в том, как реализовать чтение каждого отдельного пикселя. Кроме как getpixel(), я ничего для данного случая не знаю, а он у меня выдает кучу errors, включая fatal error. Все ошибки ведут на файл gdiplusenums.h. Как с этим бороться - я без малейшего понятия. И вот, надеялся, что, возможно, мне предложат другой путь решения проблемы.
Неизвестный
04.03.2011, 11:45
общий
Цитата: Асмик Гаряка
То есть нужна форма, в которой можно выбрать файл, его показать и т.д.?

Да, именно так. Хотя визуальную часть, я, в принципе, смог бы и сам реализовать.
Неизвестный
04.03.2011, 11:45
общий
В таком случае, укажите, откуда Вы должны считывать исходную картинку: из файла BMP или с определенной области экрана?
Неизвестный
04.03.2011, 11:47
общий
Цитата: 351298
В таком случае, укажите, откуда Вы должны считывать исходную картинку: из файла BMP или с определенной области экрана?

Из файла BMP.
Неизвестный
04.03.2011, 11:54
общий
Вот этой функцией можно прочитать BMP файл:

Код:
struct TBMPHeader{
//заголовок файла
short Type; //сигнатура BM 0x4D42
long Size; //размер файла в байтах 3*H*W+54
long Reserved; //зарезервировано 0
long OffsetBits; //смещение изображения от начала файла 54
//информационный заголовок
long SizeH; //размер заголовка 40 информационного заголовка
long Width; //ширина изображения
long Height; //высота изображения
short Planes; //число плоскостей 1
short BitCount; //глубина цвета, бит на точку 24
long Compression; //тип еомпрессии(0 - несжатое изображение)
long SizeImage; //разиер изображения, байт 3*W*H
long XPelsPerMeter; //горизонтальное разрешение, точка на метр 0
long YPelsPerMeter; //вертикальное разрешение, точка на метр 0
long ColorUsed; //число используемых цветов 0
long ColorImportant;//число основных цветов 0
};

LoadBMPFile(char *fname){
TBMPHeader BMPHeader;
FILE *f;
if ((f = fopen(fname,"rb")) == NULL){
cout<<"Ошибка открытия файла";
return;
}
fread(&BMPHeader,sizeof(TBMPHeader),1,f);

TBGR *inBGR = new TBGR[BMPHeader.Width]; //массив указателей на слова

while(!feof(f)){
fread(inBGR,3*BMPHeader.Width,1,f);
// Здесь делаете преобразования и тут же записываете в новый файл или используете по своему усмотрению.
}

fclose(f);
}
Неизвестный
04.03.2011, 12:16
общий
Цитата: 351298
TBGR *inBGR = new TBGR[BMPHeader.Width];

Может, я совсем ламер, но что это за тип такой - TBGR?
Неизвестный
04.03.2011, 12:23
общий

Код:
struct TBGR {
unsigned char b;
unsigned char g;
unsigned char r;
};
Форма ответа