2012-06-19 61 views
3

我有一個畫箱,我畫一個TBitmap這樣的:TPaintBox以JPEG/BMP - 緩衝

procedure MyForm.PaintBoxPaint(Sender: TObject); // ONPAINT 
begin 
PaintBox.Canvas.Lock; 
MyBitMap.Canvas.Lock; 
PaintBox.Canvas.Draw(0, 0, MyBitMap); 
PaintBox.Canvas.UnLock; 
MyBitMap.Canvas.UnLock; 
end; 

我想「地圖」 /「複製」,從顏料盒JPEG或BMP。 我必須首先考慮一些挑戰。 首先,我想將JPEG或BMP保存到支持WidePath/WideFileName的文件。我使用Delphi 7,而.SaveToFile程序僅支持AnsiPaths/AnsiFileNames。接下來的事情是我想創建一個獨立於「MainGUI線程」的副本。所以圖形用戶界面應該仍然是活動的,並且將它保存在背景中的同時繪製到油漆盒(所以NO TTimer)。最後一件事是「複製」的實際文件名。我想設置一個計數器,從1.jpg ...到2.jpg ...到N.jpg 問題是計數可能導致訪問衝突的整數,因爲每個函數都會嘗試增加計數器。

我的想法是以下幾點:

用於保存線程結構:

type 
PTRTSaveImage = ^TSaveImage; 
TSaveImage = record 
Number : Integer; 
Pic : TBitMap; 
end; 

實際SaveImageThread:

function SaveImageToHDD (p : pointer) : Integer; stdcall; 
var 
jpg  : TJpegImage; 
jpgStr : TStringStream; 
_infos : TSaveImage; 
begin 
CopyMemory(@_infos, p, SizeOf(_infos)); 
jpg := TJpegImage.Create; 
jpgStr := TStringStream.Create (''); 
jpg.assign (_infos.Pic); 
_infos.Pic.Free; 
jpg.SaveToStream(jpgStr); 
jpg.Free; 
StrToFile ('C:\' + inttostr(_infos.Number) + '.jpg',0,jpgStr.DataString); // for WidePath/WideFileName Support. 
jpgStr.Free; 
end; 

這就是我所說的主題:

procedure MyForm.PaintBoxPaint(Sender: TObject); // ONPAINT 
var 
Saving : PTRTSaveImage; 
BackUp : TBitMap; 
begin 
PaintBox.Canvas.Lock; 
MyBitMap.Canvas.Lock; 
PaintBox.Canvas.Draw(0, 0, MyBitMap); 
BackUp := TBitMap.Create; 
BackUp.Assign (MyBitMap); // Immediate copy of the actual drawing! 
Saving := PTRTSaveImage(LocalAlloc(LPTR, SizeOf(TSaveImage))); 
Saving^.Pic := BackUp; 
Saving^.Number := Counter; 
inc (Counter); 
PaintBox.Canvas.UnLock; 
MyBitMap.Canvas.UnLock; 
end; 

需要幾張圖片就好了,但隨後的調試器顯示我的異常:

調試故障通知 項目C:.... exe文件有消息指責:「應用程序定義的異常(code 0x0eedfade)在0x759d9617」。進程已停止。使用「步驟」或「運行」繼續。

有沒有更好的方法來做到這一點?同時保存和繪圖...?!

感謝您的幫助。

編輯:

然後我也想過只是讓1個線程作爲該是這樣的一個TTimer的替代品:

但發生同樣的錯誤/異常。

+1

OP:有任何「更好的方式」來做到這一點?同時保存和繪圖...?!。它可能更好地解釋究竟是什麼「這個」試圖達到......爲什麼你需要每秒鐘保存整個油漆盒畫布?你要創造很多照片...... – Despatcher

+0

確切。油漆盒幾乎每秒重繪(甚至更快)。我需要收集圖片,以便將它們轉換爲AVI文件。 BMP更快但非常大。我更喜歡較慢的過程(壓縮),而不是較大的文件大小。 –

回答

1

AVI文件...我想知道...我會創建一個新的從TPaintBox派生的Paintbox控件。 (您可能已經完成了這項工作?)

添加一個計數器屬性和代碼,它使用BitBlit捕獲畫布到Bmp,然後創建一個線程來轉換並將位圖保存爲jpg,並在計數器增加時遞增它開始。 (您將需要爲該呼叫使用同步)。將它命名爲CaptureCanvas。

最後添加一個名爲say的方法afterChange或調用captureCanvas的afterTimePeriod。確保你有一個嘗試......終於,確保位圖和Jpeg銷燬時,如果有任何問題。然後它在一個地方(在TNewPaintbox內部,如果它落後了,那麼正在創建的圖像已經有了它們的索引,並且不會將它們保存在無序中。只是一個想法:)

對不起意味着添加表單代碼,然後將簡化爲:

Form1.Paintboxpaint() 
begin 
. 
. 
PaintBox.Canvas.Draw(x, y, bitmap); 
Paintbox.AfterChange; 
. 

對不起,簡潔,編輯答案並不能看到原帖

+0

我讀了3次你的評論,我真的不知道你在說什麼。對不起。你能否提供一點點的代碼,因爲我有點困惑:/ –