2016-08-03 5 views
2

일단 구성 요소에 이미지를로드하고 이미지를 작성하면 Delphi에서 이미지 데이터를 DFM에 저장한다는 것을 알 수 있습니다. 예 :텍스트 데이터를 이미지로 변환하는 방법은 무엇입니까?

object img1: TImage 
    Left = 71 
    Top = 2 
    Width = 18 
    Height = 18 
    Picture.Data = { 
    0954506E67496D61676589504E470D0A1A0A0000000D49484452000000100000 
    001008060000001FF3FF610000000473424954080808087C0864880000000970 
    485973000000750000007501E3C207650000001974455874536F667477617265 
    007777772E696E6B73636170652E6F72679BEE3C1A000000EF4944415478DAAD 
    923B0AC2401086B3D7100F6110B415FBD8AB60E323E62262632DF15158A8BDB6 
    22D682E821C41B58C76F7003EB8A9A10073E36ECFCFB6766765514458E842258 
    3A5083A2F38C136C6016C5422B94EC7336C7F7122A7081A3CE97A0000768A2BD 
    BD1968F6E0428068FD2250AACE32863354ED4AE4701726D0B00F5B262BE8A199 
    DA065BC893709D2F8189547045E7D906D2D79684FFC32064F1D0E5FE6E90B985 
    CC434C738DF2F7BB7995691E521F163A1FC4262AE15396AA7650D6FBD2862F26 
    EAC313B767A0741BE64DCD657E890C0C93500F3D8E616203C344CA6FEBAD5B2A 
    03C364002D183D00658D8FCCCDEDEA100000000049454E44AE426082} 
end 

작은 이미지가 있습니다. 그것은 예를 들어, DFM없이이 정보를 얻을 수 있으며 이미지 있도록하는 것이 가능 방법 : 이미지가 먼저 TPicture에로드 될 때까지

procedure TForm12.btn2Click(Sender: TObject); 
var 
    img2: TImage; 
    Loutput: TStream; 
begin 
    ObjectTextToBinary(TStringStream.Create(
    '0954506E67496D61676589504E470D0A1A0A0000000D49484452000000100000' 
    + '001008060000001FF3FF610000000473424954080808087C0864880000000970' 
    + '485973000000750000007501E3C207650000001974455874536F667477617265' 
    + '007777772E696E6B73636170652E6F72679BEE3C1A000000EF4944415478DAAD' 
    + '923B0AC2401086B3D7100F6110B415FBD8AB60E323E62262632DF15158A8BDB6' 
    + '22D682E821C41B58C76F7003EB8A9A10073E36ECFCFB6766765514458E842258' 
    + '3A5083A2F38C136C6016C5422B94EC7336C7F7122A7081A3CE97A0000768A2BD' 
    + 'BD1968F6E0428068FD2250AACE32863354ED4AE4701726D0B00F5B262BE8A199' 
    + 'DA065BC893709D2F8189547045E7D906D2D79684FFC32064F1D0E5FE6E90B985' 
    + 'CC434C738DF2F7BB7995691E521F163A1FC4262AE15396AA7650D6FBD2862F26' 
    + 'EAC313B767A0741BE64DCD657E890C0C93500F3D8E616203C344CA6FEBAD5B2A' 
    + '03C364002D183D00658D8FCCCDEDEA100000000049454E44AE426082'), Loutput); 
    img2 := TImage.Create(self); 
    img2.Name := 'image2'; 
    img2.Left := 71; 
    img2.Top := 30; 
    img2.Width := 18; 
    img2.Height := 18; 
    img2.Picture.Graphic.LoadFromStream(Loutput); 

    img1.Parent := Self; 
end; 
+0

그것은 base16 헥스 일명 인코딩된다. 또한 앞으로 몇 가지 메타 데이터가있을 것입니다. TPicture의 소스 코드를 읽고 메타 데이터가 무엇인지 알아 낸다. 나머지는 충분히 쉽습니다. –

+0

이 상황에서는 1) 실제 DFM을 찾고 있으며 큰 DFM의 조각 일 뿐이므로이 예제에서 실패하고 2) 실패하지 않은 경우에도 'ObjectTextToBinary()'가 작동하지 않습니다. DFM 서명을 출력 스트림에 기록합니다. 건너 뛰지 않으면 이미지로드가 손상됩니다. –

답변

7

당신은 TPicture.Graphic 속성을 액세스 할 수 없습니다.

TPictureTStream (QC#12434: Add LoadFromStream() method to TPicture 참조)의 데이터를로드 할 수 없으므로 수동으로 이미지 데이터를 스트리밍해야합니다.

Picture.Data 속성 데이터는 이미지 데이터를 생성 한 TGraphic- 유도 된 클래스의 이름을 포함하는 ShortString으로 인코딩 된 UTF-8로 시작됩니다. 사용자의 예에서, 클래스 이름으로 인코딩된다 :

0954506E67496D616765 

첫번째 바이트 (16 진수 09) 클래스 이름 (9)의 바이트 수는, 다음의 9 바이트 (16 진수 54 50 6E 67 49 6D 61 67 65)는 UTF-있다 클래스 이름의 8 옥텟 (TPngImage)이며 나머지 스트림 바이트는 실제 PNG 이미지 데이터입니다.

그래서, 당신은 필요에 :

  1. 추출물 스트림에서 클래스 이름.

  2. 은 지정된 TGraphic 유래 클래스 유형을 인스턴스화합니다.

  3. 나머지 스트림을 객체에로드합니다.

  4. TPicture에 개체를 할당하십시오. 예를 들어

:

uses 
    System.Classes, 
    System.SysUtils, 
    Vcl.Graphics, 
    Vcl.Imaging.Jpeg, 
    Vcl.Imaging.GIFImg, 
    Vcl.Imaging.PngImage; 

type 
    TGraphicAccess = class(TGraphic) 
    end; 

procedure TForm12.btn2Click(Sender: TObject); 
var 
    Linput: String; 
    Loutput: TMemoryStream; 
    LclsName: ShortString; 
    Lgraphic: TGraphic; 
    img2: TImage; 
begin 
    Linput := '0954506E67496D61676589504E470D0A1A0A0000000D49484452000000100000' 
      + '001008060000001FF3FF610000000473424954080808087C0864880000000970' 
      + '485973000000750000007501E3C207650000001974455874536F667477617265' 
      + '007777772E696E6B73636170652E6F72679BEE3C1A000000EF4944415478DAAD' 
      + '923B0AC2401086B3D7100F6110B415FBD8AB60E323E62262632DF15158A8BDB6' 
      + '22D682E821C41B58C76F7003EB8A9A10073E36ECFCFB6766765514458E842258' 
      + '3A5083A2F38C136C6016C5422B94EC7336C7F7122A7081A3CE97A0000768A2BD' 
      + 'BD1968F6E0428068FD2250AACE32863354ED4AE4701726D0B00F5B262BE8A199' 
      + 'DA065BC893709D2F8189547045E7D906D2D79684FFC32064F1D0E5FE6E90B985' 
      + 'CC434C738DF2F7BB7995691E521F163A1FC4262AE15396AA7650D6FBD2862F26' 
      + 'EAC313B767A0741BE64DCD657E890C0C93500F3D8E616203C344CA6FEBAD5B2A' 
      + '03C364002D183D00658D8FCCCDEDEA100000000049454E44AE426082'; 

    Loutput := TMemoryStream.Create; 
    try 
    Loutput.Size := Length(Linput) div 2; 
    HexToBin(PChar(Linput), Loutput.Memory^, Loutput.Size); 

    LclsName := PShortString(Loutput.Memory)^; 

    Lgraphic := TGraphicClass(FindClass(UTF8Decode(LclsName))).Create; 
    try 
     Loutput.Position := 1 + Length(LclsName); 
     TGraphicAccess(Lgraphic).ReadData(Loutput); 

     img2 := TImage.Create(self); 
     img2.Parent := Self; 
     img2.Name := 'image2'; 
     img2.Left := 71; 
     img2.Top := 30; 
     img2.Width := 18; 
     img2.Height := 18; 
     img2.Picture.Assign(Lgraphic); 
    finally 
     Lgraphic.Free; 
    end; 
    finally 
    Loutput.Free; 
    end; 
end; 

initialization 
    // this is not necessary for TPicture's own DFM streaming, 
    // but it is necessary for manual streaming, unless you 
    // implement your own classname lookups... 
    // 
    RegisterClass(TMetafile); 
    RegisterClass(TIcon); 
    RegisterClass(TBitmap); 
    RegisterClass(TWICImage); 
    RegisterClass(TJpegImage); 
    RegisterClass(TGifImage); 
    RegisterClass(TPngImage); 
    // and so on... 
end. 
+0

+ !, TImage에 비트 맵 그림을 추가 한 다음 DFM 파일에서 Picture.Data를 복사하여 정적 문자열로 LInput에 할당했지만 "비트 맵 이미지가 유효하지 않습니다."라는 오류가 나타납니다. 문자열 값은 DFM의 Picture.Data 값과 같습니다. –

+1

@ G3ntle_Man : 나쁘다. 'TGraphic' 객체를 생성 한 후, 코드는'TGraphic.LoadFromStream()'대신'TGraphic.ReadData()'를 호출해야합니다. 'TBitmap'의 경우, 클래스 이름 다음과 실제 BMP 데이터 앞에 스트림 데이터 (BMP 바이트 크기)에 여분의 값이 있습니다. 'TBitmap'은 그 값을 읽을 필요가 있거나 "유효하지 않은"에러를 얻습니다. 'TPngImage'는 여분의 데이터를 가지고 있지 않습니다. 클래스 이름 이후의 스트림 데이터는 단지 PNG 데이터입니다. 지금이 문제를 설명하도록 코드를 수정했습니다. –

1
procedure TForm1.FormCreate(Sender: TObject); 
const 
    CONST_SIGN = '0954506E67496D616765'; 
var 
    LString: String; 
    LStart: Integer; 
    LStringStream: TStringStream; 
    LMem: TMemoryStream; 
    R: TBytes; 
begin 
    LString := 
    '0954506E67496D61676589504E470D0A1A0A0000000D49484452000000100000' 
    + '001008060000001FF3FF610000000473424954080808087C0864880000000970' 
    + '485973000000750000007501E3C207650000001974455874536F667477617265' 
    + '007777772E696E6B73636170652E6F72679BEE3C1A000000EF4944415478DAAD' 
    + '923B0AC2401086B3D7100F6110B415FBD8AB60E323E62262632DF15158A8BDB6' 
    + '22D682E821C41B58C76F7003EB8A9A10073E36ECFCFB6766765514458E842258' 
    + '3A5083A2F38C136C6016C5422B94EC7336C7F7122A7081A3CE97A0000768A2BD' 
    + 'BD1968F6E0428068FD2250AACE32863354ED4AE4701726D0B00F5B262BE8A199' 
    + 'DA065BC893709D2F8189547045E7D906D2D79684FFC32064F1D0E5FE6E90B985' 
    + 'CC434C738DF2F7BB7995691E521F163A1FC4262AE15396AA7650D6FBD2862F26' 
    + 'EAC313B767A0741BE64DCD657E890C0C93500F3D8E616203C344CA6FEBAD5B2A' 
    + '03C364002D183D00658D8FCCCDEDEA100000000049454E44AE426082'; 

    { Find and rid signature } 

    LStart := Pos(CONST_SIGN, LString); 

    if LStart = 0 then 
    Exit; 

    Delete(LString, LStart, Length(CONST_SIGN)); 

    { Main } 

    LStringStream := TStringStream.Create(LString); 
    LMem := TMemoryStream.Create; 
    try 
    { Prepare out array } 
    SetLength(R, Length(LString) div SizeOf(Char)); 

    { Convert } 
    HexToBin(PWideChar(LString), R, Length(LString) div SizeOf(Char)); 

    { Copy array to stream } 
    LMem.WriteBuffer(R[0], Length(R)); 

    { Save stream with image as file } 
    LMem.SaveToFile('xxx.png'); 

    { Load image from file } 
    Image1.Picture.LoadFromFile('xxx.png'); 
    finally 
    LStringStream.Free; 
    LMem.Free; 
    end; 
end; 
+0

이 답변의 문제점은 OP가 게시 한 데이터에만 국한되며 DFM에 저장된 모든 이미지 구성 요소에 대해서는 일반적이지 않습니다. 특정 이미지를 하드 코딩했습니다. –

+0

@KenWhite 예, 방금 할 수 있다는 것을 보여주는 그의 예제에 대해 더 정확한 코드를 제공했습니다. DFM에 저장된 모든 이미지 구성 요소에 대한 일반 사항 - 다른/다음 질문과 비슷하게 들립니다. – Zam

+0

이 질문은 텍스트 데이터를 이미지 *로 변환하는 방법에 대해 질문하며, * 예를 들어,이 텍스트 * (* 텍스트 유형 *의 예일뿐입니다)를 말합니다. 귀하의 대답은이 정확한 텍스트 *에 대해 말합니다. –

관련 문제