Конференция "Media" » Как изменить размер bitmap в памяти? [D7, WinXP]
 
  • {RASkov} © (29.08.07 21:18) [20]
    > [18] Pavia ©   (29.08.07 21:04)

    вот нечто такое и делается в [5].... только автору что-то все не нравится :(
    Все бы ему размер незаметно поменять, да без утечек и тормозов.... чёб всё гладко было как по маслу :)
    Записать в TBitmapInfoHeader.biWidth новое значение и не парится....а память автоматом под этот размер выстроется...

    > Dr. Andrew
    Может объяснишь подробнее что нужно-то....:)
  • Dr. Andrew (29.08.07 21:46) [21]
    Записать в TBitmapInfoHeader.biWidth новое значение и не парится. - верно подмечено. А вот если без иронии что-то в этом плане придумать можно?
  • {RASkov} © (29.08.07 21:53) [22]
    > [21] Dr. Andrew   (29.08.07 21:46)
    > А вот если без иронии что-то в этом плане придумать можно?

    Можно.... только уже придумали - TBitmap
    :)
    Впрочем если опишешь подробно что и для чего нужно, то может тебе и ответят...
    Я конкретно по вопросу в [21] тебе помочь не смогу....
  • Pavia © (29.08.07 21:55) [23]

    > А вот если без иронии что-то в этом плане придумать можно?

    Ты хочешь построить кирпичный дом без кирпичей?

    Я тебе написал. Делай свой модуль для чтения/записи бмп. И читай частично.
  • Dr. Andrew (29.08.07 23:02) [24]
    Вот есть код создания битмапа, правда недостаточно знаний дописать его:

    TMBitmap = class
     private
       { Private declarations }
         FLineSize: Integer;
         BM : THandle;
         procedure Allocate(SX,SY:integer);
     public
       { Public declarations }
       property Handle : THandle read BM;

       constructor Create(Width, Height : Integer);
       destructor Destroy; override;

       procedure LoadFromFile(const FileName:string);
     end;

    type
      TarrRGBTriple=array[byte] of TRGBTriple;
      ParrRGBTriple=^TarrRGBTriple;

    constructor TMBitmap.Create(Width, Height : Integer);
    begin
     inherited Create;
     Allocate(Width, Height);
    end;

    destructor TMBitmap.Destroy;
    begin
     inherited;
    end;

    {организует битмэп размером SX,SY;true_color}
    procedure TMBitmap.Allocate(SX,SY:integer);
    var DC:HDC;
       PB: Pointer;
       BI: tagBITMAPINFO;
    begin
     if BM<>0 then DeleteObject(BM);
     BM:=0;  PB:=nil;
     fillchar(BI,sizeof(BI),0);
     with BI.bmiHeader do
     begin
       biSize:=sizeof(BI.bmiHeader);
       biWidth:=SX;
       biHeight:=SY;
       biPlanes:=1;
       biBitCount:=24;
       biCompression:=BI_RGB;
       biSizeImage:=0;
       biXPelsPerMeter:=0;
       biYPelsPerMeter:=0;
       biClrUsed:=0;
       biClrImportant:=0;

       FLineSize:=(biWidth+1)*3 and (-1 shl 2);

       if (biWidth or biHeight)<>0 then
        begin
          DC:=CreateDC('DISPLAY',nil,nil,nil);
          BM:=CreateDIBSection(DC,BI, DIB_RGB_COLORS, pointer(PB), 0, 0);
          DeleteDC(DC);
          if BM=0 then //Error('error creating DIB');
        end;
     end;
    end;

    procedure TMBitmap.LoadFromFile(const FileName : string);
    var HF:integer; {file handle}
       HM:THandle; {file-mapping handle}
       PF:pchar;   {pointer to file view in memory}
       i,j:integer;
       Ofs:integer;
       BI: tagBITMAPINFO;
    begin
    {открываем файл}
     HF:=FileOpen(FileName,fmOpenRead or fmShareDenyWrite);
     if HF<0 then //Error('open file '''+FileName+'''');
     try
      { создаем объект-проецируемый файл }
       HM:=CreateFileMapping(HF,nil,PAGE_READONLY,0,0,nil);
       if HM=0 then //Error('can''t create file mapping');
       try
        {собственно проецируем объект в адресное }
         PF:=MapViewOfFile(HM,FILE_MAP_READ,0,0,0);
        {получаем указатель на область памяти, в которую спроецирован файл}
         if PF=nil then //Error('can''t create map view of file');
         try
          { работаем с файлом как с областью памяти через указатель PF}
           if PBitmapFileHeader(PF)^.bfType<>$4D42 then  //Error('file format');
             Ofs:=PBitmapFileHeader(PF)^.bfOffBits;
           with PBitmapInfo(PF+sizeof(TBitmapFileHeader))^.bmiHeader do
           begin
             if (biSize<>40) or (biPlanes<>1) then //Error('file format');
             if (biCompression<>BI_RGB)or(biBitCount<>24) then //Error('only true-color BMP supported');
              { выделяем память под битмэп }
               Allocate(biWidth,biHeight);
           end;

           for j:=0 to BI.bmiHeader.biHeight-1 do
             for i:=0 to BI.bmiHeader.biWidth-1 do
              { Pixels - это property, возвр. указатель на соотв. RGBTriple в битмэпе}
              //Pixels[i,j]^.Tr:=ParrRGBTriple(PF+j*FLineSize+Ofs)^[i];
         finally
           UnmapViewOfFile(PF);
         end;
       finally
         CloseHandle(HM);
       end;
     finally
       FileClose(HF);
     end;
    end;



    создать битмап можно (черного цвета поле):

    procedure TForm1.FormCreate(Sender: TObject);
    begin
     BMP := TMBitmap.Create(40, 20);
    end;



    но нарисовать на нем или загрузить в него (особенно нужно через поток) ничего нельзя. Как можно этот код изменить чтобы работать с ним как с обычным битмапом. Только загрузка процедурой LoadFromfile интересует меньit всего. Спасибо!
  • Pavia © (29.08.07 23:38) [25]
    А чем тогда TBitmap не угодил?
    Поток, просто считываешь в буфер. Дальше, разбираем заголовок. А битовое поле заносим через SetDIBits
  • Dr. Andrew (30.08.07 00:13) [26]
    А можно пример небольшой как скорректировать приведенный код? Спасибо.
 
Конференция "Media" » Как изменить размер bitmap в памяти? [D7, WinXP]
Есть новые Нет новых   [134431   +10][b:0][p:0.003]