3

我有一个在 Delphi 2006 中开发的旧应用程序,现在需要对其进行一些更改。

在这个应用程序中,我从 MsSQL“图像”字段加载图像,但是当我使用 delphi 2010 编译时出现错误:“引发异常类 EJPEG,消息为 'JPEG 错误 #51'。”

从数据库中获取图像的代码:

aStream := TMemoryStream.Create;
Try
If LoadFromBlob(FieldByName('Picture'), aStream) then
begin
    Pic:=TJpegImage.Create;

    try
        Try
            Pic.LoadFromStream(aStream);
            Picture.Assign(Pic); // <------ JPEG Error #51 here w D2010
        Except
            //something went wrong loading
            HandleImageError();    
        End;

    finally
     Pic.Free;
    end;

end;
Finally
    aStream.Free;
End;

// ............

function LoadFromBlob(const AField: TField; const Stream: TStream): boolean;
var
    ResultStr: string;
    PResultStr: PChar;
begin
    Result := false;
    if (Assigned(AField)) and (Assigned(Stream)) then begin
        try
            ResultStr := AField.Value;
            If ResultStr <> '' then
            begin
                PResultStr := PChar(ResultStr);
                Stream.Write(PResultStr^, Length(ResultStr));
                Stream.Seek(0,0);
                Result := true;
            end;
        except
        end;
    end;
end;

谷歌了一下,发现错误 #51 的意思是:JERR_NO_QUANT_TABLE,不管是什么意思。

当我用 Delphi 2006 编译时,相同的代码可以正常工作,没有错误,那么 D2010 出了什么问题?

4

4 回答 4

4

在 D2010 中,字符从 Ansi 更改为 Unicode,这意味着它占用了两个字节而不是一个。将 LoadFromBlob 中的变量更改为 AnsiString 和 PAnsiChar ,它应该可以工作。

更新:而不是 Field.Value (Variant) 你应该更好地访问 Field.AsAnsiString; 变体访问可能包括引入错误的隐式 Unicode->Ansi 转换。

于 2010-09-01T13:12:18.840 回答
3

您正在使用一种相当尴尬的方式将 blob 字段保存到流中。你为什么不使用TBlobField.SaveToStream

于 2010-09-01T14:18:03.027 回答
1

将您的 aStream 保存到文件中并使用十六进制编辑器进行检查。比较 D2006 和 D2010 结果。您在那里发现的内容应该让您相信这与 JPEG 标头无关,而且很可能是 Unicode/Widechar 问题。

于 2010-09-01T14:04:33.857 回答
1

无论如何,为什么要越过字符串?直接写入流呢?图像字段可能是 TBlobField 或 TGraphicField。那些具有完全适合您需求的 SaveToStream 方法。

于 2010-09-01T14:19:43.837 回答