C ++: Scratch-dan Bitmap şəklini necə yazmaq olar.

Şəkil emalı, kompleks obyekt aşkarlanmasına qədər sadə süzgəci əhatə edən geniş mövzudur. Dərinliyə getmək və bir görüntünün kompüterdə necə saxlandığını öyrənmək istəyənlər üçün bu başlamaq üçün ən uyğun yerdir.

Bu dərslikdə sadə bir cyan rəngli bitmap şəklini necə yazacağını görəcəyik.

Baxış

Bu dərslikdə istifadə olunan yanaşma yalnız az-az bayan formatında məlumatları emal edən sistemlərə uyğundur (əksər Intel və AMD maşınlarında istifadə olunur).

Ön şərtlər:

  • C ++ əsas bilikləri

I. İkili Fayl Formatlarına Giriş

İkili bir fayl, bir sənəddə saxlanılan bit yəni 1s və 0s toplusudur. Ən çox ikili fayl formatlarında məlumat bayt byte, bayt isə 8 bit toplusudur. Baytlar məlumatı saxlamaq üçün qaydada qurulmuşdur. Ən çox ikili fayllarda iki əsas hissə var:

  • Başlıq

İkili bir fayldakı başlıq meta məlumatlarını ehtiva edir (məlumatlar haqqında əlavə məlumat, məsələn, görüntünün eni və hündürlüyü).

  • Bədən

İkili bir sənədin gövdəsində faktiki məlumatlar var. Bitmap faylı olduqda, bu görüntüdəki hər piksel haqqında məlumatdır.

II. Bitmap faylı nədir?

Bitmap faylı əsasən dəyişən ölçüdə bir başlıqdan ibarətdir, lakin ən çox istifadə olunan başlıq 54 baytdır. Bu dərslikdə 24 bit Bitmap şəkli yazacağıq. 24 bit bit təsvir ölçüsündə hər pikselin dəyəri var. Hər bir piksel hər kanalın 1 bayt olduğu BGR (mavi, yaşıl və qırmızı) ardıcıllıqla 3 rəngli kanaldan ibarətdir. Buna görə 24 bit bitlik xəritəsi faylındakı hər piksel 3 bayt (və ya 24 bit) təşkil edir.

(Bitmap sənəd formatının təfərrüatlarını yoxlamaq üçün: Bitmap-Xüsusiyyətlər)

III. Kod

(Tam Misal Kodu üçün: Buraya vurun)

  • Standard Kitabxanalar daxil olmaqla:
# daxil edin // xüsusi ölçülü tam ədədlər üçün
# daxil edin // işləmə üçün
ad boşluğu std istifadə;
  • Başlıq yaratmaq:

Bitmap faylında meta məlumatları üçün iki başlıq var. Birinci başlıq (bitmap file header) bu ikili faylın bitmap faylı olduğunu bildirir. Növbəti başlıq (bitmap info başlığı) görüntü haqqında əlavə meta məlumatları ehtiva edir.

Bitmap faylının başlığı (14 bayt) üçün aşağıdakı məlumat strukturunu yaratmalıyıq:

struktur BmpHeader {
char bitmapSignatureBytes [2] = {'B', 'M'};
uint32_t ölçüsüOfBitmapFile = 54 + 786432;
uint32_t qorunurBytes = 0;
uint32_t pixelDataOffset = 54;
} bmpHeader;

İlk iki bayt 'B' və 'M' bitmap formatı üçün unikaldır (bunun fərqli versiyaları hələ bitmap formatının dəqiqləşdirilməsini yoxlayır). Növbəti dörd bayt bayt ilə bitmap faylının ümumi ölçüsünü ehtiva edir. 512 ilə 512 bit təsvir ölçüsü yaratdığımız üçün ümumi ölçü meta məlumatlarının ölçüsü (14 + 40 = 54 bayt) və piksel ölçüsü (512 * 512 * 3 = 7863432), hər piksel 24 baytda 3 baytdır. bit bit xəritəsi faylı). Bitmap faylı başlığının son sahəsində, faylın başlanğıcından görüntünün piksel məlumatlarına əvəzləşdirmə yer alır. Bizim vəziyyətimizdə ofset 54 baytdır, çünki piksel məlumatlarımız bitmap fayl başlığı və məlumat başlığından dərhal sonra (14 + 40 = 54).

Bitmap faylı müxtəlif məlumat başlıqlarına malikdir, lakin ən çox yayılanı 40 bayt Bitmap Info Header olduğundan onu aşağıdakı məlumat strukturunda yazmalıyıq:

struktur BmpInfoHeader {
uint32_t ölçüsüOfThisHeader = 40;
int32_t eni = 512;
int32_t boyu = 512;
uint16_t sayıOfColorPlanes = 1; // 1 olmalıdır
uint16_t colorDepth = 24;
uint32_t sıxılmaMethod = 0;
uint32_t xamBitmapDataSize = 0;
int32_t üfiqiResolution = 3780; // metrə piksel ilə
int32_t verticalResolution = 3780; // metrə piksel ilə
uint32_t colorTableEntries = 0;
uint32_t əhəmiyyətliColors = 0;
} bmpInfoHeader;

Bitmap faylının hündürlüyü də mənfi ola bilər (imzalanmış tam ədədləri görmüş ola bilərsiniz). Boy yüksək olduqda, fayldakı ilk piksel görüntünün yuxarı sol tərəfində çəkilir. Lakin, bitmap faylları üçün standart müsbət hündürlükdən istifadə etməkdir və fayldakı ilk piksel digər piksellərin ardınca görüntünün sol alt tərəfində çəkilir.

Bitmap faylında rəng cədvəli də ola bilər, lakin 24 bit bit xəritəsi sənədində məcburi deyil, buna görə də bu nümunədə birini yaratmayacağıq.

  • Piksel yaratmaq:

Mono rəngli bit şəkli görüntüsü yaradacağam (bütün piksellər eyni dəyərə malikdir), mən piksel üçün əlavə bir quruluş yaradıram:

struktur Pixel {
uint8_t mavi = 255;
uint8_t yaşıl = 255;
uint8_t qırmızı = 0;
} piksel;

Bir pikseldəki hər kanal 24 bit bit faylı üçün 1 bayt imzalanmamış tam sayda olmalıdır. Burada 255 maksimum rəng intensivliyini və 0 rəngin olmamasını göstərir.

  • Əsas funksiya:
int main (int argc, char ** argv) {
ofstream fout ("çıxış.bmp", ios :: ikili);
fout.write ((char *) & bmpHeader, 14);
fout.write ((char *) & bmpInfoHeader, 40);
// piksel məlumatlarını yazmaq
size_t sayıOfPixels = bmpInfoHeader.width * bmpInfoHeader.height;
for (int i = 0; i 
fout.write ((char *) & piksel, 3);
}
fout.close ();
qayıt 0;
}

Bir quruluş, performansını optimallaşdırmaq üçün tərtibçi tərəfindən əlavə edilmiş doldurma (əlavə bayt) ola bilər. Beləliklə sizeof () dəqiq dəyəri qaytarmaq niyyətində deyil. Beləliklə, hər bir quruluşun ölçüsünü ofstream :: write () metodunda əl ilə göstərdim.

IV. Nəticə

Beləliklə, ilk bitmap sənədinizi yazmağı bacarsanız, özünüzə çiynində pat verin. Bundan sonra bitmap xüsusiyyətlərini yoxlamaq üçün müxtəlif növ bitmap fayllarını yazmaqda maraqlı ola bilərsiniz. Kudos və öyrənməyə davam edin!