Announcement

Collapse
No announcement yet.

TAdoBlobField+Jpeg+TImage

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • TAdoBlobField+Jpeg+TImage

    Hallo #,<p>
    ich fummele mir hier gerade einen Wolf mit einem JPeg, das sich in einem Recordset befindet.<br>Erzeugt wird das Record wie folgt (mit Hilfe von Herrn Kosch).
    <pre>
    procedure TForm1.Button1Click(Sender: TObject);
    var
    aADOStream : _Stream;
    begin
    FRecordset := CreateComObject(CLASS_Recordset) as _Recordset;
    FRecordset.CursorLocation := adUseClient;
    FRecordset.Fields.Append('Field1',adVarChar,10,adF ldUnspecified);
    FRecordset.Fields.Append('Field2',adVarChar,10,adF ldUnspecified);
    FRecordset.Fields.Append('Field3',adLongVarBinary, 100000,adFldUnspecified);
    // Recordset öffnen
    FRecordset.Open(EmptyParam, EmptyParam, adOpenUnspecified,
    adLockUnspecified, 0);
    // immediate update mode anfordern (Edit-Modus des Recordset)
    OleVariant(FRecordset).AddNew;
    FRecordset.Fields.Item['Field1'].Value := 'Test 1';
    FRecordset.Fields.Item['Field2'].Value := 'Test 2';
    // Stream-Objekt von ADO lädt die BLOb-Daten
    aADOStream := CoStream.Create;
    aADOStream.Type_ := adTypeBinary;
    aADOStream.Open(EmptyParam, adModeUnknown,
    adOpenStreamUnspecified, '', '');
    aADOStream.LoadFromFile('C:\WINDOWS\Angler.jpj');
    FRecordset.Fields.Item['Field3'].Value := aADOStream.Read(adReadAll);
    FRecordset.Update(EmptyParam, EmptyParam);
    end;
    </pre>
    Nun zu der Frage. Ich benötige Höhe und Breite des Jpeg. Das Recordset ist schon offen.<br>
    Das müßte doch über TAdoBlobStream + TImage.Picture.LoadFromStream gehen.?<p>
    Mit der Bde ist das alles kein Problem. Ich habe aber leider in Recordset.<p>
    Kann mir jemand auf die Sprünge helfen mit ein paar Code-Schnipseln ?<br>
    Mein Delphi wirft mit unverständlichen Meldungen im sich.
    <p>
    Danke im voraus<br>
    Heiko

  • #2
    Hallo,
    folgendes Beispiel funktioniert auch ohne das ADOStream-Objekt und damit auch mit älternen ADO Versionen.<p>
    Die beiden folgenden Funktionen sind auch von A. Kosch wie ich glaube sogar hier im Forum schon diskutiert.<p>

    <pre>
    unit OS_StreamVariant;

    interface

    uses Classes, Variants;

    procedure OleVariantToStream(var Input: OleVariant; Stream: TStream);
    function StreamToOleVariant(Stream: TStream; Count: Integer): OleVariant;

    implementation

    type
    TByteArray = array of Byte;

    procedure OleVariantToStream(var Input: OleVariant; Stream: TStream);
    var
    pBuf: Pointer;
    begin
    pBuf := VarArrayLock(Input);
    Stream.Write(TByteArray(pBuf^), Length(TByteArray(Input)));
    Stream.Seek(0, soFromBeginning);
    VarArrayUnlock(Input);
    end;

    function StreamToOleVariant(Stream: TStream; Count: Integer): OleVariant;
    var
    pBuf: Pointer;
    begin
    if Count>0 then begin
    Result := VarArrayCreate([0, Count-1], varByte);
    pBuf := VarArrayLock(Result);
    Stream.Read(TByteArray(pBuf^), Length(TByteArray(Result)));
    VarArrayUnlock(Result);
    end else Result := null;
    end;

    end.</pre><p>

    Damit geht dann das hantieren mit JPegs z.B. wie folgt:<p><pre>
    function TfrmBilder1.LoadPicture(ID: String): TJpegImage;
    const
    cSQL ='SELECT Picture FROM Bilder WHERE (ID=%s) AND (Picture IS NOT Null)';
    var
    sSQL : String;
    aRS : _RecordSet;
    aOleV : OleVariant;
    aStr : TMemoryStream;
    aJPeg : TJPegImage;
    begin
    aRS := CoRecordSet.Create;
    aRS.CursorLocation := adUseServer;
    aStr := TMemoryStream.Create;
    sSQL := Format(cSQL,[ID]);
    Result := nil;
    try
    aRS.Open(sSQL, FConnection,adOpenStatic, adLockReadOnly, adCmdText);
    if aRS.RecordCount>0 then begin
    aOleV := aRS.Collect[0];
    OleVariantToStream(aOleV,aStr);
    aJPeg := TJPegImage.Create;
    aJPeg.LoadFromStream(aStr);
    Result := aJPeg;
    end;
    finally
    aRS.Close;
    aStr.Free;
    end;
    end;</pre&gt

    Comment

    Working...
    X