Einzelnen Beitrag anzeigen

Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: Canvas in ein RTF-Dokument speichern ?

  Alt 8. Jan 2007, 11:48
Ein RTF mit einem Bild drin zu verschicken ist nicht die feine Art...

Ich hab aus einem alten Projekt mal relevanten Code rausgesucht um das RTF händig zu erstellen. Vielleicht gibts auch einfacher Varianten.

Hier die Funktion um aus einer BMP-Datei (du kannst ja das Canvas als Bitmap nehmen) ein RTF-Kompatibles Bild zu machen und in eine RTF-Datei zu schreiben
Delphi-Quellcode:
procedure TRTF.WritePictureFramepos(const PictureFile:string;posx,posy:integer;maxwidth:integer=0;maxheight:integer=0);
var i:integer;
    jpg:tjpegimage;
    bmp:tbitmap;
    hoehe,breite,nbreite,nhoehe:integer;
    mem:TMemorystream;
    data:string;
    b:^Byte;
begin
  if length(picturefile)=0 then exit;

  //Bild aus Datei laden
  jpg:=tJpegimage.Create;
  if lowercase(ExtractFileExt(PictureFile))='.bmpthen begin
    bmp:=tbitmap.Create;
    try
      bmp.LoadFromFile(Picturefile);
    except
      exit;
    end;
    //aus bmp ein jpg machen
    jpg.Assign(bmp);
    bmp.Free;
  end else if (lowercase(ExtractFileExt(PictureFile))='.jpg')or
              (lowercase(ExtractFileExt(PictureFile))='.jpeg')or
              (lowercase(ExtractFileExt(PictureFile))='.jpe') then begin
    try
      jpg.LoadFromFile(pictureFile);
    except
      exit;
    end;
  end else exit;
  jpg.JPEGNeeded;
  hoehe:=jpg.Height*20; //Einheiten in TWIPS umrechnen
  breite:=jpg.Width*20;
  mem:=Tmemorystream.Create;
  jpg.SaveToStream(mem);
  mem.Seek(0,sofrombeginning);
  b:=mem.Memory;
  data:='';
  for i:=1 to mem.Size do begin
    data:=data+inttohex(b^,2); //angaben RTF-Kompatibel machen -->Hex
    inc(b);
  end;
  mem.Free;
  jpg.Free;

  //Skalieren auf maxwidth und/oder maxheight
  nbreite:=breite;
  nhoehe:=hoehe;
  maxwidth:=maxwidth*20;
  maxheight:=maxheight*20;
  if (nbreite>maxwidth)and(maxwidth>0) then begin
    nhoehe:=round(nhoehe/(nbreite/maxwidth));
    nbreite:=maxwidth;
  end;
  if (nhoehe>maxheight)and(maxheight>0) then begin
    nbreite:=round(nbreite/(nhoehe/maxheight));
    nhoehe:=maxheight;
  end;


  //negative Positionswerte (von unteren/rechten seitenrand) umrechnen
  if posx<0 then begin
    inc(posx);
    posx:=9071+posx*20-nbreite;
  end else posx:=posx*20;
  if posy<0 then begin
    inc(posy);
    posy:=14288+posy*20-nhoehe;
  end else posy:=posy*20;

  //shape=True: Bild auf freie Position setzen
  if shape then begin
    writeln(datei,format('{\shp{\*\shpinst\shpleft%d\shptop%d\shpright%d\shpbottom%d',[posx,posy,posx+nbreite,posy+nhoehe]),
                  '\shpbypara\shpwr3\shpwrk0{\sp{\sn shapeType}{\sv 75}}{\sp{\sn pib}{\sv');
  end else if withpos then writeln(Datei,'\pard\pvmrg\phmrg\posx'+inttostr(posx)+'\posy'+inttostr(posy)+'\absw'+inttostr(nbreite)+'\absh'+inttostr(nhoehe)+'\dxfrtext80');
  writeln(Datei,'{\pict\jpegblip\picw'+inttostr(breite)+'\pich'+inttostr(hoehe)+'\picwgoal'+inttostr(nbreite)+'\pichgoal'+inttostr(nhoehe));
  writeln(Datei,data,'}');
  if shape then writeln(Datei,'\par\pard }}}}')
           else writeln(Datei,'\par\pard ');

end;
Wie du siehst, schreibt die Funktion gleich in ein textfile (Datei). Und diese Datei wird das RTF.
Dazu gibts noch einen RTF-Header: Der könnte so aussehen (und muss am anfang der Datei stehen):
Delphi-Quellcode:
write(Datei,'{\rtf1 \ansi\ansicpg1252');
  writeln(Datei,'\deff0{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial;}}');
  writeln(Datei,'{\colortbl;\red0\green0\blue0;\red210\green255\blue210;\red255\green255\blue210;\red255\green255\blue210;\red255\green210\blue210;\red255\green255\blue255;}');
  writeln(Datei,'{\info{\title ',Titel,'}{\subject ',Inhalt,'}{\author ',Bearbeiter,'}{\company ',
          Firma,'}{\category Protokoll}{\comment Created by Maxi Musterfrau}{\doccomm '+messort+'}{\version1}{\creatim\yr',
          yearof(Zeit),'\mo',monthof(Zeit),'\dy',dayof(Zeit),'\hr',hourof(Zeit),
          '\min',minuteof(Zeit),'\sec',secondof(Zeit),'}}');
  writeln(Datei,'\paperw11907\paperh16840\margl1418\margr1418\margt1418\margb1134 ');
  writeln(Datei,'\viewkind1\viewzk2\uc1\pard ');
(Wenn du nur ein Bild reinlegen willst, ist min. die Farbtabelle für dich irrelevant)

Davor und dahinter musst du natürlich noch die Datei anlegen und schließen:
Delphi-Quellcode:
system.rewrite(Datei);
...
writeheader
...
writepictureframpos
...

write(Datei,'}'); //nicht vergessen
system.close(Datei);
Soviel zum Erstellen von RTF. Falls sonst kein anderer Tipp kommt mit einer tollen Komponente und du diesen, meinen, Teil umsetzen musst, kannst du gerne weiterfragen (ich weis, dass Kommentare nicht so meine Stärke sind )


Edit: Statt eines Jpegs kann man in RTF acuh EMF, PNG und noch andere direkt ablegen, falls dir das lieber ist. Watch This!
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat