суббота, 20 ноября 2010 г.

Мал мал о программировании

Чтобы не забыть и не потерять.
Маленько на тему программирования


http://www.gamedev.ru/code/forum/?id=39676

http://www.cplusplus.com/forum/beginner/4307/

http://www.cplusplus.com/forum/general/6500/

Вот тут готовый код - вывод в файл
http://delphi.about.com/od/graphics/l/aa101803a.htm

Рисование
http://www.realcoding.net/teach/Delphi7_prof/Glava10/Index11.html
Var line : pByteArray;
For i:=0 to Imagel.Picture.Bitmap.Height — 1 do
 Begin
Line := Imagel.Picture.Bitmap.ScanLine[i];
 For j:=0 to Imagel.Picture.Bitmap.Width * 3 - 1 do
 Line^[j] := 255 - Line^[j];
 End;

This is just typed-in; it may have errors:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// float2bmp2.hpp
//
// Copyright 2010 Michael Thomas Greer
// Distributed under the Boost Software License, Version 1.0.
// (See http://www.boost.org/LICENSE_1_0.txt )
// 

#pragma once
#ifndef FLOAT2BMP2_HPP
#define FLOAT2BMP2_HPP

#include 
#include 

namespace float2bmp2
  {

  //-------------------------------------------------------------------------- 
  // This little helper is to write little-endian values to file.
  //
  struct lwrite
    {
    unsigned long value;
    unsigned      size;
    lwrite( unsigned long value, unsigned size ):
      value( value ), size( size )
      { }
    };

  //--------------------------------------------------------------------------
  inline std::ostream& operator << ( std::ostream& outs, const lwrite& v )
    {
    unsigned long value = v.value;
    for (unsigned cntr = 0; cntr < v.size; cntr++, value >>= 8)
      outs.put( static_cast <char> (value & 0xFF) );
    return outs;
    }

  //--------------------------------------------------------------------------
  template <typename Iterator>
  bool
  floats_to_bitmap_file(
    const char*   filename,
    Iterator      begin,
    Iterator      end,
    size_t        rows,
    size_t        columns,
    unsigned char default_value = 0
    ) {
    std::ofstream f( filename, std::ios::out | std::ios::trunc | std::ios::binary );
    if (!f) return false;

    // Some basic
    unsigned long headers_size    = 14  // sizeof( BITMAPFILEHEADER )
                                  + 40; // sizeof( BITMAPINFOHEADER )
    unsigned long padding_size    = (4 - ((columns * 3) % 4)) % 4;
    unsigned long pixel_data_size = rows * ((columns * 3) + padding_size);

    // Write the BITMAPFILEHEADER
    f.put( 'B' ).put( 'M' );                           // bfType
    f << lwrite( headers_size + pixel_data_size, 4 );  // bfSize
    f << lwrite( 0,                              2 );  // bfReserved1
    f << lwrite( 0,                              2 );  // bfReserved2
    f << lwrite( headers_size,                   4 );  // bfOffBits

    // Write the BITMAPINFOHEADER
    f << lwrite( 40,                             4 );  // biSize
    f << lwrite( columns,                        4 );  // biWidth
    f << lwrite( rows,                           4 );  // biHeight
    f << lwrite( 1,                              2 );  // biPlanes
    f << lwrite( 24,                             2 );  // biBitCount
    f << lwrite( 0,                              4 );  // biCompression=BI_RGB
    f << lwrite( pixel_data_size,                4 );  // biSizeImage
    f << lwrite( 0,                              4 );  // biXPelsPerMeter
    f << lwrite( 0,                              4 );  // biYPelsPerMeter
    f << lwrite( 0,                              4 );  // biClrUsed
    f << lwrite( 0,                              4 );  // biClrImportant

    // Write the pixel data
    for (unsigned row = rows; row; row--)           // bottom-to-top
      {
      for (unsigned col = 0; col < columns; col++)  // left-to-right
        {
        unsigned char value;
        double        d = 0.0;

        // If we haven't overrun the end of our input, convert it to a grayscale value.
        // Input is clamped to the range [0, 1], where 0 --> black and 1 --> white.
        if (begin != end)
          {
          d = *begin++;
          
          if      (d < 0.0) d = 0.0;
          else if (d > 1.0) d = 1.0;

          value = 255 * d;
          }

        // Otherwise we just use the default grayscale value
        else value = default_value;

        f.put( static_cast <char> (value) )
         .put( static_cast <char> (value) )
         .put( static_cast <char> (value) );
        }

      if (padding_size) f << lwrite( 0, padding_size );
      }

    // All done!
    return f.good();
    }

  } // namespace float2bmp2

#endif

// end float2bmp2.hpp 
 
====================================================== 
Write your own 24 bit BMP
Did you ever dream of writing your own bitmap image? A 24 bit Bitmap file is relatevely simple to write. We should have an understading of BMP's header and should know how to write the data part. This article shows how.
 Win prizes by sharing code!
Do you have some Delphi code you want to share? Are you interested in winning a prize for your work?
Delphi Programming Quickies Contest
 Join the Discussion
"Post your views, comments, questions and doubts to this article."
Discuss!
 Related Resources
• GDI graphics in Delphi
• Handling images using Delphi
• Graphics programming
Article submitted by Thaha Hussain for the Delphi Programming Quickies Contest.
What is a header?
Let's learn the header of BMP. A header is a place where the picture's basic information is stored. For example, colors used, width of the picture, height of the picture etc. The following is the header structure of a standard 24 bit BMP file. bfType1 : Byte ; (* "B" *)
bfType2 : Byte ; (* "M" *)
bfSize : LongInt ; (* Size of File. Zero is acceptable *)
bfReserved1 : Word ; (* Zero *)
bfReserved2 : Word ; (* Zero *)
bfOffBits : LongInt ; (* Offset to beginning of BitMap *)
biSize : LongInt ; (* Number of Bytes in Structure *)
biWidth : LongInt ; (* Width of BitMap in Pixels *)
biHeight : LongInt ; (* Height of BitMap in Pixels *)
biPlanes : Word ; (* Planes in target device = 1 *)
biBitCount : Word ; (* Bits per Pixel 1, 4, 8, or 24 *)
biCompression : LongInt ; (* BI_RGB = 0, BI_RLE8, BI_RLE4 *)
biSizeImage : LongInt ; (* Size of Image Part (often ignored) *)
biXPelsPerMeter : LongInt ; (* Always Zero *)
biYPelsPerMeter : LongInt ; (* Always Zero *)
biClrUsed : LongInt ; (* Number of Colors used in Palette *)
biClrImportant : LongInt ; (* Number of Colors that are Important *)

In a 24 bit BMP, the header is immediately followed by the picture's data.
The art of writing a binary file
Usually the basic unit of a binary file is byte. The data type, 'word' (please see the header) needs 2 bytes to store and LongInt needs 4 bytes. So the above header needs a total of 54 bytes storage space. We can now write files byte-wise. But using a structure is very easy and standard practice in writing these type of files.
Few elementary things regarding the binary file
The picture below is the screen-shot of a BMP opened in a Hex Editor. Hex Editor is a tool for viewing any file in its elementary form. There are two panes. On the left side, there is numbers in Hex and in right, its equivalent ASCII. The ASCII character 'B' is the equivalent of the Hex number 42 (Number 66 in our normal decimal system and is not seen in Hex Editor). The bytes which cannot be represented in ASCII is shown as a dot (.) in the right pane. One who dosen't know how to convert Hex to decimal (though it is simple) can use the Windows calculator in Scientific mode.



The portion selected represents the header of the BMP (54 Bytes). The remainig bytes are used for keeping the picture's data.
Important: Long Integer (4 bytes) is represented in a Hex file from Right to Left (As Arabic is written). For example, the Hex representation of Long Intger (0A) (00) (00) (00) is actually (00) (00) (00) (0A).
In the above example, width and height of the HelloWorld.BMP is both 10 pixels. 10 in decimal is (0A) or (00) (00) (00) (0A) in Hexadecimal. As we all know, the zeroes in the left side will not alter the value of a number! And in a hex Editor it is seen in reverse!
The reverse rule and zero padding is applicable for data type 'word' also (2 bytes). Zeroes are padded to maintain the size of the data type.
By now, we undestood the secret of Hex editing.
The Data Part
The data of a BMP is stored as Pixels(Picture Elements). A Pixel is a combination of 3 bytes.1 byte for Blue, 1 byte for Green and 1 byte for Red. The maximum value for each is 'FF' in Hex (255 in Decimal).

Pure Red is Blue - 00, Green - 00 and Red in FF. In other words, (00) (00) (FF) will represent a red pixel. In our demonstration we are writing a pale magenta BMP. So, it would be, (FF) (CC) (FF). The first FF for Blue, CC for Green and the last FF for Red.
Few things to remember
1) Unfortunately, BMP data is not written from left to right -> left to right etc (like we read a book), insted it is written from right to left -> right to left etc from Bottom to Top. That means writing of pixel data starts from Bottom Right and ends in Top Left. In our example the problem will not reflect, since all the 100 (10 x 10) pixels are same pale magenta!

2) The number of bytes of the Picture Data in one each row should be a multiple of 4. We have to padd extra zeroes to kame it a multiple of 4. In our case, the picture's width is 10 pixels. So find the remainder of the division 10 / 4. The remainder is 2. So TWO zero bytes should be padded with each row's data.
The following is the program source you can use to test your own bitmap image format. Place a TButton on the Form and paste the code below...

//---------------------------------------------------------------------
//                 Write your own  24 Bit BMP
//           (C) K.O. Thaha Hussain MCA, 2003 Sept
//          I used Hexadecimal Numbers just for Style
//            Hex editors make use of that system.
//   (Example $28 in Hex is Equal to 40 in decimal system. You can make use
//              either hex or Decimal system
// --------------------------------------------------------------------

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, 
  Controls, Forms, Dialogs, StdCtrls, Buttons;


Type
 TBmpHeader = Packed Record
  bfType1         : Byte;
  bfType2         : Byte;
  bfSize          : LongInt;
  bfReserved1     : Word;
  bfReserved2     : Word;
  bfOffBits       : LongInt;
  biSize          : LongInt;
  biWidth         : LongInt;
  biHeight        : LongInt;
  biPlanes        : Word;
  biBitCount      : Word;
  biCompression   : LongInt;
  biSizeImage     : LongInt;
  biXPelsPerMeter : LongInt;
  biYPelsPerMeter : LongInt;
  biClrUsed       : LongInt;
  biClrImportant  : LongInt;
 End ;

   // Each pixel is a combination of Blue, Green and Red Values
   // In other words, A pixel is uniquely represented by 3 bytes
   // Maximum Value of any of them is $FF (255 in Decimal)
   TRGB = Record
         rgbBlue : BYTE;  //intensity of blue in the color
         rgbGreen: BYTE;  //intensity of green in the color
         rgbRed  : BYTE;  //intensity of red in the color
   End;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}


procedure TForm1.Button1Click(Sender: TObject);
 Var
  MyBitmapHeader : TBmpHeader;
  MyRGB : TRGBQUAD;
  MyFile : File;
  MyBuffer : Byte ;

  i, j : Integer;
begin
  With MyBitmapHeader do
  Begin
    bfType1         :=  $42;  
    bfType2         :=  $4D;  
    bfSize          :=  $00000000;
    bfReserved1     :=  $0000;
    bfReserved2     :=  $0000;
    bfOffBits       :=  $36; 
    biSize          :=  $28;
    biWidth         :=  $0000000A;
    biHeight        :=  $0000000A;
    biPlanes        :=  $0001;
    biBitCount      :=  $0018;
    biCompression   :=  $00000000;
    biSizeImage     :=  $00000000;
    biXPelsPerMeter :=  $00000000;
    biYPelsPerMeter :=  $00000000;
    biClrUsed       :=  $00000000;
    biClrImportant  :=  $00000000;
  end;

  //Open output file
  AssignFile(MyFile, 'C:\HelloWorld.BMP');
  Rewrite(MyFile,1);

  //Finish writing the Header
  BlockWrite (MyFile, MyBitmapHeader, SizeOf(TBmpHeader)); 


  //Now starts the data part

  MyRGB.rgbBlue :=$FF;
  MyRGB.rgbGreen  := $cc;
  MyRGB.rgbRed := $FF;

  //  This will be a pale magenta color 
  //  For Bright Red:-   Blue = $00, Green =$00 and Red= $FF 


  for i:= 1 to 10 do
  begin
     for j:= 1 to 10 do
     begin
         BlockWrite(MyFile, MyRGB, 3); //Block size is 3 bytes
     end;
    //Two Zeroes should be padded  
    //to make each row a multiple of 4
    // ie,  10 mod 4  = 2 (zeroes should be 
    //padded two times)
    MyBuffer := $00;
    BlockWrite(MyFile, MyBuffer, 1);
    MyBuffer := $00;
    BlockWrite(MyFile, MyBuffer, 1);
 end;

  CloseFile(MyFile);
  ShowMessage ('BMP file is successfully written!');
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  Caption:= 'Thaha Hussain''s 24 bit BMP creation demonstration';
  Button1.Caption:= 'Write my BMP';
end;

end.


case VK_F2:
{
static OPENFILENAME ofn;
static char szFile[256];
static char szFileTitle[256];
static char CustomFilter;
ofn.lStructSize      = sizeof(OPENFILENAME);
ofn.hwndOwner        = hWnd;
ofn.nFilterIndex      = 1;
ofn.lpstrFile        = szFile;
ofn.nMaxFile          = sizeof(szFile);
ofn.lpstrFileTitle    = szFileTitle;
ofn.nMaxFileTitle    = sizeof(szFileTitle);
ofn.lpstrCustomFilter = (LPSTR)CustomFilter;
ofn.Flags=OFN_OVERWRITEPROMPT;
ofn.lpstrTitle="Сохрание карты";
char szFilter[256]="Файлы IRKLAB MAP EDITOR \0*.bmp";
ofn.lpstrFilter=szFilter;
szFile[0]='\0';
if(GetSaveFileName(&ofn))
{
strcat(szFile,".bmp");
char str[512];
strcpy(str,"Путь:\t");
strcat(str,szFile);
strcat(str,"\n\nИмя созранёной карты:\t");
strcat(str,szFileTitle);
HANDLE hFile;
DWORD RW;
// Объявим нужные структуры
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
BYTE Palette [1024];
// Пусть у нас будет картинка размером 52 x 40 пикселей
int Width = 52;
int Height = 40;
memset (Palette, 0, 1024);// В палитре у нас нули
RGBTRIPLE color[2080];
int t1=0;
int t2=39;
// Дальше с примудростями.
for(i=0;i
{
for(j=0;j
{
color[a[j]].rgbtRed  =  b1[t1][t2];
color[a[j]].rgbtGreen =  b2[t1][t2];
color[a[j]].rgbtBlue  =  b3[t1][t2];
t1++;
}
t1=0;
t2--;
}
// Заполним их
memset (&bfh, 0, sizeof(bfh));
bfh.bfType = 0x4D42;// Обозначим, что это bmp 'BM'
bfh.bfOffBits = sizeof(bfh) + sizeof(bih) + 1024;// Палитра занимает 1Kb, но мы его испоьзовать не будем
memset (&bih, 0, sizeof(bih));
bih.biSize = sizeof(bih);// Так положено
bih.biBitCount = 24;// 16 бит на пиксель
bih.biCompression = BI_RGB;// Без сжатия
bih.biHeight = Height;
bih.biWidth = Width;
bih.biPlanes = 1;
// Должно быть 1
// А остальные поля остаются 0
hFile = CreateFile (szFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
// Запишем заголовки
WriteFile (hFile, &bfh, sizeof (bfh), &RW, NULL);
WriteFile (hFile, &bih, sizeof (bih), &RW, NULL);
// Запишем палитру
WriteFile (hFile, Palette, 1024, &RW, NULL);
for (i = 0; i < Height; i++)
{
for (j = 0; j < Width; j++)
{
WriteFile (hFile, &color[a[j]], sizeof(color[a[j]]), &RW, NULL);
}
// Выровняем по границе
WriteFile (hFile, Palette, Width % 4, &RW, NULL);
}
CloseHandle(hFile);
}
}
break; case VK_F3:
{
int Width = 52;
int Height = 40;
static OPENFILENAME ofn;
static char szFile[256];
static char szFileTitle[256];
static char CustomFilter;
ofn.lStructSize      = sizeof(OPENFILENAME);
ofn.hwndOwner        = hWnd;
ofn.nFilterIndex      = 1;
ofn.lpstrFile        = szFile;
ofn.nMaxFile          = sizeof(szFile);
ofn.lpstrFileTitle    = szFileTitle;
ofn.nMaxFileTitle    = sizeof(szFileTitle);
ofn.lpstrCustomFilter = (LPSTR)CustomFilter;
ofn.Flags=OFN_EXPLORER|OFN_CREATEPROMPT|OFN_ALLOWMULTISELECT;
ofn.lpstrTitle="Открытие карты";
char szFilter[256]="Файлы IRKLAB MAP EDITOR \0*.bmp";
ofn.lpstrFilter=szFilter;
szFileTitle[0]='\0';
szFile[0]='\0';
if(GetOpenFileName(&ofn))
{
char str[512];
strcpy(str,"Список имен файлов:\t");
for (int i=0;i<255;i++)
{
if(szFile=='\0' && szFile[i+1]=='\0')
break;
if(szFile=='\0') szFile='\n';
}
strcat(str,szFile);
strcat(str,"\n\nИмя карты:\t");
strcat(str,szFileTitle);
}
HBITMAP    hbm;// дескриптор битмапа
BITMAP      bm;// битмап
COLORREF    pix;// цвет
hbm = (HBITMAP) LoadImage (NULL, szFile,
IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION); // загрузка битмап из файла
GetObject (hbm, sizeof(bm), &bm); // получение объекта из битмапа
HDC hdc = CreateCompatibleDC (0); // создание DC для извлечения информации по цветам
SelectObject (hdc, hbm);// выбор объекта битмапа
for (i=0;i
{
for(j=0;j
{
pix = GetPixel (hdc,i, j);
b1
[j]=(GetRValue(pix));
b2[j]=(GetGValue(pix));
b3[j]=(GetBValue(pix));
}
}
ReleaseDC (0, hdc);// освобождение дескриптора
DeleteObject(hbm);// удаление объекта битмапа
}
break;

Комментариев нет:

Отправить комментарий