2009-06-20 2 views
2

여기와 코드 뉴스 연구 빠른 속도로, 나는 내 문제를 지적하지 않았습니다. 사용자가 내 앱의 버튼을 클릭하여로드 할 때 타사 사진 촬영 프로그램에서 클립 보드를 통해 고객 사진 (JvDBImage)을 가져 오는 앱이 있습니다. (PhotoImage.PasteFromClipboard). 그것은 이미지를 비트 맵으로로드하고 저장합니다 ... 때로는 큰 BMP입니다. 따라서 JPG를 저장하고로드하는 데 필요한 것이 필요합니다. Paradox를 사용하여 Delphi 7에서 BMP에서 JPG 로의 실시간 변환

내가 시도 : 있습니다 .. 대입이 두 가지 유형의 때문에, 컴파일되지 않습니다 어떤
var 
    jpg  : TJpegImage; 
begin 
    PhotoImage.PasteFromClipboard; 
// // convert to JPEG 
// jpg.Create; 
// jpg.Assign(PhotoImage.Picture); 
// PhotoImage.Picture := jpg; 
// freeAndNil(jpg); 
end; 

JPEG

사용합니다. 클립 보드에서 작업하면서 시간을 보내고 성공없이 TMemoryStream으로 가져 오려고했습니다.

내 다음 시도는 일시적으로 파일에 저장 한 다음 JPG로 검색하는 것이지만 속도가 느려지고 내가하려는 일이 가능하지 않은 것입니다. 따라서, 다른 골목 아래로 내려 가기보다는, 여기에 질문을 게시 할 것이라고 생각했습니다.

해당 데이터베이스에는 PhotoImage가 연결된 메모 (1) 필드라는 Photo가 있습니다.

답변

3

This page 적어도 JPEG 클립 보드의 콘텐츠를 변환하는 방법을 보여줍니다

uses 
    Jpeg, ClipBrd; 

procedure TfrmMain.ConvertBMP2JPEG; 
    // converts a bitmap, the graphic of a TChart for example, to a jpeg 
var 
    jpgImg: TJPEGImage; 
begin 
    // copy bitmap to clipboard 
    chrtOutputSingle.CopyToClipboardBitmap; 
    // get clipboard and load it to Image1 
    Image1.Picture.Bitmap.LoadFromClipboardFormat(cf_BitMap, 
    ClipBoard.GetAsHandle(cf_Bitmap), 0); 
    // create the jpeg-graphic 
    jpgImg := TJPEGImage.Create; 
    // assign the bitmap to the jpeg, this converts the bitmap 
    jpgImg.Assign(Image1.Picture.Bitmap); 
    // and save it to file 
    jpgImg.SaveToFile('TChartExample.jpg'); 
end; 

이 코드는 매우 불완전하고 나는 그것이 올바른 있는지 모르겠지만 사용하는 방법을 잘해야하고 shouldn ' (예를 들어, cf_BitMap은 HBITMAP이어야하며 이미 저장된 데이터가있는 것처럼 보이는 "CopyToClipboardBitmap"라인은 필요하지 않습니다.) 이미지 품질 및 기타 매개 변수를 필요에 맞는 값으로 설정하려면 TJPEGImage 클래스를 살펴 봐야합니다.

큰 이미지를 실시간으로 처리하려면, 사용할 수있는 JPG 라이브러리를 찾아야합니다. 델파이 루틴보다 성능이 좋은 것도 있습니다.

+0

이것은 내 kludge 아이디어의 근처에 있습니다. Mike Shkolnik의 아이디어 기반 루틴을 사용한 나의 시도는 고통스럽게 느려지면 이것이 가능하다는 것을 시사한다. 나는 빠르고 간단한 코드 렛 솔루션을 원했지만 제 3 자 전문 라이브러리는 점점 더 필요하게 보입니다. 노력해 주셔서 감사합니다. GM –

0

다음은 몇 년 전에 내가 JPEG 이미지를 처리하기 위해 작성한 코드의 일부입니다. 그것은로드 및 jpeg 파일을 저장, BLOB 필드에서 jpeg 데이터를 저장 및 검색, 그리고 jpeg와 bmp 사이의 변환을 보여줍니다.

'_proper'절차는 JPEG -> BMP -> JPEG에서 이미지를 다시 압축하는 것을 보여줍니다. '_update_display'프로시 저는 캔버스에 TJpegImage를 그려 사용자가 볼 수있게하는 방법을 보여줍니다.

//Take the supplied TJPEGImage file and load it with the correct 
//data where _gas_check_key is pointing to. 
//Return 'true' on success, 'false' on failure. 
function TfrmGcImage._load_image(var image: TJPEGImage): Boolean; 
var 
    blob_stream: TStream; 
begin 
    //Get the current image into image_field 
    _query_current_image(); 

    blob_stream := Query1.CreateBlobStream 
     (Query1.FieldByName('GcImage') as TBlobField, bmRead); 
    try 
     _load_image := False; 
     if blob_stream.Size > 0 then 
     begin 
      image.LoadFromStream(blob_stream); 
      _load_image := True; 
     end; 
    finally 
     blob_stream.Free; 
    end; 
end; 

{ Extract Exif information representing the dots per inch of the physical 
    image. 

    Arguments: 
     file_name: name of file to probe 
     dpi_h: horizontal dpi or 0 on failure. 
     dpi_v: vertical dpi or 0 on failure. 

    Returns: True for successful extraction, False for failure 
} 
function TfrmGcImage._get_dpi 
    (file_name: string; var dpi_h, dpi_v: Integer): Boolean; 
var 
    exif: TExif; 
begin 
    exif := TExif.Create; 
    try 
     exif.ReadFromFile(file_name); 
     dpi_h := exif.XResolution; 
     dpi_v := exif.YResolution; 
    finally 
     exif.Free; 
    end; 

    //Even though the file did have Exif info, run this check to be sure. 
    _get_dpi := True; 
    if (dpi_h = 0) or (dpi_v = 0) then 
     _get_dpi := False; 
end; 

procedure TfrmGcImage._update_display(); 
var 
    image_jpeg: TJPEGImage; 
    thumbnail: TBitmap; 
    dest_rect: TRect; 
begin 
    thumbnail := TBitmap.Create; 
    try 
     image_jpeg := TJpegImage.Create; 
     try 
      if (not _load_image(image_jpeg)) or (not _initialized) then 
       _load_no_image_placeholder(image_jpeg); 
      thumbnail.Width := Image1.Width; 
      thumbnail.Height := Image1.Height; 
      dest_rect := _scale_to_fit 
       (Rect(0, 0, image_jpeg.Width, image_jpeg.Height) 
       , Rect(0, 0, thumbnail.Width, thumbnail.Height)); 
      thumbnail.Canvas.StretchDraw(dest_rect, image_jpeg); 
     finally 
      image_jpeg.Free; 
     end; 
     Image1.Picture.Assign(thumbnail); 
    finally 
     thumbnail.Free; 
    end; 
end; 

{ 
    Calculate a TRect of the same aspect ratio as src scaled down to 
    fit inside dest and properly centered 
} 
function TfrmGcImage._scale_to_fit(src, dest: TRect): TRect; 
var 
    dest_width, dest_height: Integer; 
    src_width, src_height: Integer; 
    margin_lr, margin_tb: Integer; 
begin 
    dest_width := dest.Right - dest.Left; 
    dest_height := dest.Bottom - dest.Top; 
    src_width := src.Right - src.Left; 
    src_height := src.Bottom - src.Top; 


    //Must not allow either to be larger than the page 
    if src_width > dest_width then 
    begin 
     src_height := Trunc(src_height * dest_width/src_width); 
     src_width := dest_width; 
    end; 
    if src_height > dest_height then 
    begin 
     src_width := Trunc(src_width * dest_height/src_height); 
     src_height := dest_height; 
    end; 

    margin_lr := Trunc((dest_width - src_width)/2); 
    margin_tb := Trunc((dest_height - src_height)/2); 

    _scale_to_fit.Left := margin_lr + dest.Left; 
    _scale_to_fit.Right := dest.Right - margin_lr; 
    _scale_to_fit.Top := margin_tb + dest.Top; 
    _scale_to_fit.Bottom := dest.Bottom - margin_tb; 
end; 

{ 
    Take a Jpeg image and resize + compress 
} 
procedure TfrmGcImage._proper(var image: TJpegImage; dpi_h, dpi_v: Integer); 
var 
    scale_h, scale_v: Single; 
    bitmap: TBitmap; 
begin 
    scale_h := dpi/dpi_h; 
    scale_v := dpi/dpi_v; 

    bitmap := TBitmap.Create; 
    try 
     bitmap.Width := Trunc(image.Width * scale_h); 
     bitmap.Height := Trunc(image.Height * scale_v); 
     bitmap.Canvas.StretchDraw 
      (Rect 
       (0, 0 
       , bitmap.Width 
       , bitmap.Height) 
      , image); 
     with image do 
     begin 
      Assign(bitmap); 
      JPEGNeeded(); 
      CompressionQuality := 75; 
      GrayScale := True; 
      DIBNeeded(); 
      Compress(); 
     end; 
    finally 
     bitmap.Free; 
    end; 

end; 

procedure TfrmGcImage.Import1Click(Sender: TObject); 
var 
    blob_stream: TStream; 
    image: TJPEGImage; 
    dpi_h, dpi_v: Integer; 
    open_dialog: TOpenPictureDialog; 
    file_name: string; 
begin 
    if not _initialized then Exit; 

    //locate file to import. 
    open_dialog := TOpenPictureDialog.Create(Self); 
    try 
     open_dialog.Filter := GraphicFilter(TJpegImage); 
     open_dialog.Title := 'Import'; 
     if not open_dialog.Execute() then Exit; 
     file_name := open_dialog.FileName; 
    finally 
     open_dialog.Free; 
    end; 

    image := TJpegImage.Create(); 
    try 
     try 
      image.LoadFromFile(file_name); 
     except 
      ShowMessage(file_name + ' could not be imported.'); 
      Exit; 
     end; 
     if not _get_dpi(file_name, dpi_h, dpi_v) then 
     begin 
      if not _get_dpi_from_user 
       (image.Width, image.Height, dpi_h, dpi_v) then Exit 
      else if (dpi_h = 0) or (dpi_v = 0) then Exit; 
     end; 

     _proper(image, dpi_h, dpi_v); 

     //Create a TBlobStream to send image data into the DB 
     _query_current_image(); 
     Query1.Edit; 
     blob_stream := Query1.CreateBlobStream 
      (Query1.FieldByName('Gcimage') as TBlobField, bmWrite); 
     try 
      image.SaveToStream(blob_stream); 
     finally 
      Query1.Post; 
      blob_stream.Free; 
     end; 
    finally 
     image.Free; 
    end; 

    _update_display(); 
end; 

procedure TfrmGcImage.Export1Click(Sender: TObject); 
var 
    save_dialog: TSavePictureDialog; 
    blob_stream: TStream; 
    image: TJpegImage; 
    file_name: string; 
begin 
    if not _initialized then Exit; 

    //decide where to save the image 
    save_dialog := TSavePictureDialog.Create(Self); 
    try 
     save_dialog.DefaultExt := GraphicExtension(TJpegImage); 
     save_dialog.Filter := GraphicFilter(TJpegImage); 
     if not save_dialog.Execute() then Exit; 
     file_name := save_dialog.FileName; 
    finally 
     save_dialog.Free; 
    end; 

    //locate the appropriete image data 
    _query_current_image(); 

    //Create a TBlobStream to send image data into the DB 
    Query1.Edit; 
    blob_stream := Query1.CreateBlobStream 
     (Query1.FieldByName('Gcimage') as TBlobField 
     , bmRead); 
    image := TJpegImage.Create(); 
    try 
     image.LoadFromStream(blob_stream); 
     image.SaveToFile(file_name); 
    finally 
     Query1.Post; 
     blob_stream.Free; 
     image.Free; 
    end; 
end; 
+0

귀하의 답변과 많은 코드의 공헌에 감사드립니다. 궁극적으로 상용 솔루션을 결정했습니다. ImageEn이 문제를 해결했습니다. –

+0

@GMMugford : ImageEn의 opensource 버전이 있습니다. –