::: 델파이 Tip&Trick :::

델파이 Tip&Trick 성격에 맞지 않는 광고,비방,질문의 글은 즉시 삭제하며
내용을 복사하여 사용할 경우 반드시 이곳(http://www.howto.pe.kr)을 출처로 명시하여 주세요


Category

  김영대(2003-03-04 20:49:13, Hit : 5429, Vote : 1218
 Image의 90도 회전

안녕하세요  김영대입니다
아래는 제가 사용했었던 자료인데요
무리없이 잘 실행되었습니다
참고하세요

"Here's code to rotate a bitmap 90
degrees"

From: Dave Shapiro

Counterclockwise, that is. This rotates a 640x480 24-bit bitmap 90 degrees in
about 2/10 of sec on my P133 (4MB video card, 128MB RAM). It works for
Delphi 2, and should work for 1 and 3, too.

One thing: This does not work for bitmaps that aren't an integral number of colors
per pixel. If that's the case, you'll have to do some bit twiddling. I'm working on that
part right now (I need it too), but it'll be a few days. Anyways, suggestions,
comments, etc., always welcome.

Special thanks to David Ullrich (ooh, I hope I spelled that correctly) for pointing out
the non-published-but-public-anyway SaveToStream method for the TBitmap class.

Advance apologies for any formatting problems. Netscape's editor is so ridiculously
crippled that I can't accomplish anything (give me rtin and vim any day).



procedure RotateBitmap90Degrees(ABitmap: TBitmap);

const
  BITMAP_HEADER_SIZE = SizeOf(TBitmapFileHeader) +
SizeOf(TBitmapInfoHeader);

var
  { Things that end in R are for the rotated image. }
  PbmpInfoR: PBitmapInfoHeader;
  bmpBuffer, bmpBufferR: PByte;
  MemoryStream, MemoryStreamR: TMemoryStream;
  PbmpBuffer, PbmpBufferR: PByte;
  PbmpBufferRFirstScanLine, PbmpBufferColumnZero: PByte;
  BytesPerPixel, BytesPerScanLine, BytesPerScanLineR: Integer;
  X, Y, T: Integer;

begin
  {
    Don't *ever* call GetDIBSizes! It screws up your bitmap.
    I'll be posting about that shortly.
  }

  MemoryStream := TMemoryStream.Create;

  {
   To do: Put in a SetSize, which will eliminate any reallocation
   overhead.
  }

  ABitmap.SaveToStream(MemoryStream);

  {
   Don't need you anymore. We'll make a new one when the time comes.
  }
  ABitmap.Free;

  bmpBuffer := MemoryStream.Memory;

  { Set PbmpInfoR to point to the source bitmap's info header. }
  { Boy, these headers are getting annoying. }
  Inc( bmpBuffer, SizeOf(TBitmapFileHeader) );
  PbmpInfoR := PBitmapInfoHeader(bmpBuffer);

  { Set bmpBuffer to point to the original bitmap bits. }
  Inc(bmpBuffer, SizeOf(PbmpInfoR^));
  { Set the ColumnZero pointer to point to, uh, column zero. }
  PbmpBufferColumnZero := bmpBuffer;

  with PbmpInfoR^ do
  begin
    BytesPerPixel := biBitCount shr 3;
    { ScanLines are DWORD aligned. }
    BytesPerScanLine := ((((biWidth * biBitCount) + 31) div 32) * SizeOf(DWORD));
    BytesPerScanLineR := ((((biHeight * biBitCount) + 31) div 32) * SizeOf(DWORD));

    { The TMemoryStream that will hold the rotated bits. }
    MemoryStreamR := TMemoryStream.Create;
    {
     Set size for rotated bitmap. Might be different from source size
     due to DWORD aligning.
    }
    MemoryStreamR.SetSize(BITMAP_HEADER_SIZE  + BytesPerScanLineR * biWidth);
  end;

  { Copy the headers from the source bitmap. }
  MemoryStream.Seek(0, soFromBeginning);
  MemoryStreamR.CopyFrom(MemoryStream, BITMAP_HEADER_SIZE);

  { Here's the buffer we're going to rotate. }
  bmpBufferR := MemoryStreamR.Memory;
  { Skip the headers, yadda yadda yadda... }
  Inc(bmpBufferR, BITMAP_HEADER_SIZE);

  {
   Set up PbmpBufferRFirstScanLine and advance it to end of the first scan
   line of bmpBufferR.
  }
  PbmpBufferRFirstScanLine := bmpBufferR;
  Inc(PbmpBufferRFirstScanLine, (PbmpInfoR^.biHeight - 1) * BytesPerPixel);

  { Here's the meat. Loop through the pixels and rotate appropriately. }

  { Remember that DIBs have their origins opposite from DDBs. }
  for Y := 1 to PbmpInfoR^.biHeight do
  begin
    PbmpBuffer := PbmpBufferColumnZero;
    PbmpBufferR := PbmpBufferRFirstScanLine;

    for X := 1 to PbmpInfoR^.biWidth do
    begin
      for T := 1 to BytesPerPixel do
      begin
        PbmpBufferR^ := PbmpBuffer^;
        Inc(PbmpBufferR);
        Inc(PbmpBuffer);
      end;
      Dec(PbmpBufferR, BytesPerPixel);
      Inc(PbmpBufferR, BytesPerScanLineR);
    end;

    Inc(PbmpBufferColumnZero, BytesPerScanLine);
    Dec(PbmpBufferRFirstScanLine, BytesPerPixel);
  end;

  { Done with the source bits. }
  MemoryStream.Free;

  { Now set PbmpInfoR to point to the rotated bitmap's info header. }
  PbmpBufferR := MemoryStreamR.Memory;
  Inc( PbmpBufferR, SizeOf(TBitmapFileHeader) );
  PbmpInfoR := PBitmapInfoHeader(PbmpBufferR);

  { Swap the width and height of the rotated bitmap's info header. }
  with PbmpInfoR^ do
  begin
    T := biHeight;
    biHeight := biWidth;
    biWidth := T;
  end;

  ABitmap := TBitmap.Create;

  { Spin back to the very beginning. }
  MemoryStreamR.Seek(0, soFromBeginning);
  ABitmap.LoadFromStream(MemoryStreamR);

  MemoryStreamR.Free;
end;






411   [COM/OLE] 내 프로그램에서 선택한 text를 다른 프로그램에 Drag&Drop으로 주기  김영대 2004/12/10 5805 1225
410   [COM/OLE] TWebBrowser에서 JavaScript 호출하기  김영대 2004/10/09 5565 1225
409   [일반/컴포넌트] Task bar 에 나타나는 프로그램 아이콘 바꾸기  김영대 2004/08/11 5067 1225
408   [데이터베이스] DB에서 자음(ㄱ,ㄴ,ㄷ....)으로 SELECT 하기  김영대 2003/03/12 5168 1225
407   [일반/컴포넌트] 한글이 포함된 문자열 자르기 - 반쪽 한글  김영대 2003/03/04 6355 1225
406   [윈도우즈 API] 실행중인 모든 프로그램 Minimized 시키기  김영대 2003/03/06 4607 1224
405   [윈도우즈 API] 원도우 이동시 다시 그리기 설정/해제  김영대 2003/03/07 4500 1223
404   [데이터베이스] 테이블,인덱스 복사하기  김영대 2003/03/07 4078 1223
403   [시스템] 윈도우즈 서비스 목록 구하기  김영대 2004/07/22 4521 1222
402   [네트웍/인터넷] Winsock WriteFile and Overlapped IO  김영대 2003/11/18 5384 1222
401   [시스템] 윈도우즈 전체의 키보드 입력 금지  김영대 2003/03/07 4558 1222
400   [멀티미디어] JPEG, WAVE 를 resource 파일에 넣고 읽어오기  김영대 2003/03/06 5138 1222
399   [윈도우즈 API] 정의되지 않은 Alt+키 입력시 Beep음 제거  김영대 2003/03/07 4336 1221
398   [윈도우즈 API] 작업관리자의 task switching 금지시키기  김영대 2003/03/07 4638 1221
397   [일반/컴포넌트] TForm을 BMP파일로 저장하기  김영대 2003/03/05 4810 1221
396   [일반/컴포넌트] 한 장당 두 페이지 인쇄하기  김영대 2003/03/05 4760 1221
395   [윈도우즈 API] 떠다니는 윈도우  김영대 2003/03/05 4540 1220
394   [일반/컴포넌트] LZExpand를 사용한 파일 복사하기  김영대 2003/03/04 4045 1220
393   [시스템] DOS-matrix 프린터에 인쇄하기  김영대 2003/03/07 4520 1219
392   [시스템] Locking/ Unlocking floppy driver or CD  김영대 2003/03/07 4268 1218
391   [시스템] 현재 내 PC의 비디오 정보  김영대 2003/03/04 4565 1218
  [일반/컴포넌트] Image의 90도 회전  김영대 2003/03/04 5429 1218
389   [시스템] 윈도우즈 캡션의 높이 읽기/설정  김영대 2003/03/07 4436 1217
388   [알고리즘] 임의의 밑수(radix)를 사용한 진법변환  김영대 2004/12/08 4889 1216
387   [일반/컴포넌트] 문자열 프로시저명으로 실제 프로시저 호출하기2  김영대 2004/10/08 4767 1216
386   [윈도우즈 API] Active Desktop 활성화 여부  김영대 2004/08/25 4638 1216
385   [일반/컴포넌트] IE Toolbar 에 버튼 올리기  김영대 2003/03/26 4752 1215
384   [윈도우즈 API] 휴지통에 파일을 버리는 법  신훈재 2003/03/10 4578 1215
383   [윈도우즈 API] Window Handle 로 실행파일명 구하기  김영대 2003/03/07 4701 1215
382   [윈도우즈 API] Taskbar 감추기/보이기  김영대 2003/03/05 4656 1215
381   [일반/컴포넌트] 주어진 문자열에 잘못된 숫자값이 들어있는지 검사  김영대 2003/03/04 4182 1215
380   [일반/컴포넌트] ListView 의 item 을 강제로 편집상태로 만들기  김영대 2003/03/07 4604 1213
379   [일반/컴포넌트] ListBox의 내용을 파일로 저장하고 불러오기  김영대 2003/03/04 4334 1213
378   [시스템] 윈도우즈 부팅 모드(정상, 안전)  김영대 2004/08/05 4250 1212
377   [일반/컴포넌트] Windows의 사용자이름, 작업그룹 구하기  김영대 2003/04/01 4854 1212
376   [일반/컴포넌트] Form이 생성되어 있는지 검사하기  김영대 2003/03/05 4113 1212
375   [윈도우즈 API] 윈도우즈 "시작" 메뉴 표시하기/감추기  김영대 2003/03/07 4532 1211
374   [시스템] 기본 프린터가 있어야 실행하지 ?  김영대 2003/03/05 4568 1211
373   [일반/컴포넌트] TEdit의 OnChange에서 Text 바꾸기  김영대 2003/03/04 4171 1211
372   [일반/컴포넌트] StringGrid의 Column의 크기(width) 자동 조절  김영대 2003/03/04 6628 1211

[이전 10개] [1]..[11][12][13][14] 15 [16][17][18][19][20]..[25] [다음 10개]
 

Copyright 1999-2021 Zeroboard / skin by zero