Podmienky:
- predpokladám u programátora základné znalosti z C++ a objektového programovania
- nastavenie projektu v sekcii "Bitmaps Property pages":
- Use of MFC: Use Standard Windows Libraries
- Character set: Use Unicode Character Set
- Common Language Runtime support: Pure MSIL Common Language Runtime Support (/clr:pure)
- Whole Program optimalization: No whole Program optimalization
Projekt som nazval "Bitmaps", namespace takisto "Bitmaps". Hlavný obsah zdrojového kódu je uložený v súbore Form1.h.
V prílohe sú dva súbory Bitmaps.cpp a Form1.h a dva testovacie obrázky na ukážku motorhead1.bmp a motorhead2.bmp.

Na formulári sú vložené 4 objekty Picturebox. Picturebox1 a Picturebox2 slúžia ako zdroj pre obrázok po skombinovaní bitmáp do jednej a vložení nového bitmapového obrázku do objektu Picturebox3. Po štarte aplikácie si nakopírujte obrázky do adresára, kde sa nachádza výsledný spustiteľný súbor Bitmaps.exe a môžete skúšať. Nahrajte pomocou tlačidla "Load picture 1" prvý obrázok, pomocou tlačidla "Load picture 2" druhý, nastavte percentuálny odtieň druhého obrázku v prvom pomocou objektu "trackBar1" a stlačte tlačidlo "Combine pictures". Výsledok je vidno ihneď. Pootočenie obrázku "Picturebox2" je možné tlačidlom "Rotate picture". Nastavte uhol pootočenia a stlačte tlačidlo. Obrázok z objektu "Picturebox2" bude pootočený a zobrazený v objekte "Picturebox4".
Malé vysvetlenie k programu.
Kombinácia obrázkov spočíva v prečítaní RGB čísla farby každého jedného bodu "pixelu" oboch bitmáp, rozložení farby na R,G a B zložky a vypočítaní z nich nového RGB čísla farby z nových zložiek RGB. Rovnica výpočtu je jednoduchá a zo zrdrojového kódu zrejmá. Ide o rozdelenie pomeru pôvodných RGB zložiek podľa nastaveného pomeru odtieňu od jednej farby k druhej. Pomery sú sčítané a súčet nových pomerov zložky tvorí novú zložku. Nové čislo farby sa potom vypočíta zo všetkých nových RGB zložiek.
Rotácia obrázku spočíva v prečítaní RGB čísla farby bodu, vypočítaní novej súradnice bodu pootočenú o zadaný uhol v objekte "numericUpDown1" a nastavení tohto čísla farby RGB do nového bodu. Rovnice pootočenia sú vidno v zdrojom kóde takisto a trochu si nimi pripomenieme matematiku zo strednej školy.:)
Kód v CPP - mixBitmaps:
private: System::Drawing::Bitmap^ MixBitmaps(System::Drawing::Bitmap^ bitmap1,
System::Drawing::Bitmap^ bitmap2,
int steps,
int stepno)
{
//typedef unsigned char * buffer;
int h = bitmap1->Height < bitmap2->Height ? bitmap1->Height : bitmap2->Height;
int w = bitmap1->Width < bitmap2->Width ? bitmap1->Width : bitmap2->Width;
// Check if h or w are nonzero ...
if (h == 0 && w == 0)
{
throw std::invalid_argument("Bitmaps must be loaded!");
}
this->progressBar1->Value = 0;
System::Drawing::Bitmap^ result = gcnew Bitmap(w, h, System::Drawing::Imaging::PixelFormat::Format24bppRgb);
System::Drawing::Color color, color1, color2;
int R, G, B;
double s1 = (double) (steps - stepno) / (double) steps;
double s2 = (double) stepno / (double) steps;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
color1 = bitmap1->GetPixel(x, y);
color2 = bitmap2->GetPixel(x, y);
R = color1.R * s1 + color2.R * s2;
G = color1.G * s1 + color2.G * s2;
B = color1.B * s1 + color2.B * s2;
color = System::Drawing::Color::FromArgb(R, G, B);
result->SetPixel(x, y, color);
}
this->progressBar1->Value = Math::Floor ((double) y * (100 / (double) h));
this->progressBar1->Refresh();
}
this->progressBar1->Value = 0;
return result;
}
Kód v CPP - rotateBitmap:
private: System::Drawing::Bitmap^ RotateBitmap(System::Drawing::Bitmap^ src_bitmap, int angle_deg)
{
int h = src_bitmap->Height;
int w = src_bitmap->Width;
// Check if h or w are nonzero ...
if (h == 0 && w == 0)
{
throw std::invalid_argument("Bitmap must be loaded!");
}
this->progressBar1->Value = 0;
System::Drawing::Bitmap^ result = gcnew Bitmap(w, h, System::Drawing::Imaging::PixelFormat::Format24bppRgb);
System::Drawing::Color color;
double angle_rad = 2 * Math::PI * (double) angle_deg / 360;
double cosin_angle = Math::Cos(angle_rad);
double sin_angle = Math::Sin(angle_rad);
double cx = (double) w / 2.0;
double cy = (double) h / 2.0;
int nx, ny;
double deltaX, deltaY;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
deltaX = (double) x - cx;
deltaY = (double) y - cy;
nx = Math::Floor(deltaX * cosin_angle + deltaY * sin_angle + cx);
ny = Math::Floor(deltaY * cosin_angle - deltaX * sin_angle + cy);
if (nx >= 0 && nx < w && ny >= 0 && ny < h)
{
color = src_bitmap->GetPixel(x, y);
result->SetPixel(nx, ny, color);
}
}
this->progressBar1->Value = Math::Floor ((double) y * (100 / (double) h));
this->progressBar1->Refresh();
}
this->progressBar1->Value = 0;
return result;
}
Príjemnú zábavu.
S pozdravom







