2012-02-07 11 views
8

अगर मैं एक TBitmap है और मैं इस बिटमैप से एक फसली छवि प्राप्त करना चाहते हैं, मैं फसल आपरेशन "स्थान पर" प्रदर्शन कर सकते हैं? जैसे अगर मैं एक बिटमैप वह यह है कि 800x600, मैं कैसे कम कर सकते हैं (फसल) है यह इतना है कि यह केंद्र में 600x400 छवि, यानी जिसके परिणामस्वरूप TBitmap 600x400 है शामिल है, और आयत द्वारा (100, 100) और (700 घिरा के होते हैं , 500) मूल छवि में?डेल्फी - मैं "जगह में" बिटमैप कैसे फसल करूं?

मैं एक बिटमैप के माध्यम से जाने की जरूरत है या इस आपरेशन मूल बिटमैप के भीतर किया जा सकता है है?

उत्तर

20

आप BitBlt समारोह

उपयोग कर सकते हैं इस कोड का प्रयास करें।

procedure CropBitmap(InBitmap, OutBitMap : TBitmap; X, Y, W, H :Integer); 
begin 
    OutBitMap.PixelFormat := InBitmap.PixelFormat; 
    OutBitMap.Width := W; 
    OutBitMap.Height := H; 
    BitBlt(OutBitMap.Canvas.Handle, 0, 0, W, H, InBitmap.Canvas.Handle, X, Y, SRCCOPY); 
end; 

और आप इस तरह से उपयोग कर सकते हैं

Var 
    Bmp : TBitmap; 
begin 
    Bmp:=TBitmap.Create; 
    try 
    CropBitmap(Image1.Picture.Bitmap, Bmp, 10,0, 150, 150); 
    //do something with the cropped image 
    //Bmp.SaveToFile('Foo.bmp'); 
    finally 
    Bmp.Free; 
    end; 
end; 

आप एक ही बिटमैप का उपयोग करना चाहते हैं, समारोह

procedure CropBitmap(InBitmap : TBitmap; X, Y, W, H :Integer); 
begin 
    BitBlt(InBitmap.Canvas.Handle, 0, 0, W, H, InBitmap.Canvas.Handle, X, Y, SRCCOPY); 
    InBitmap.Width :=W; 
    InBitmap.Height:=H; 
end; 

के इस संस्करण की कोशिश और इस तरह से उपयोग करने

Var 
Bmp : TBitmap; 
begin 
    Bmp:=Image1.Picture.Bitmap; 
    CropBitmap(Bmp, 10,0, 150, 150); 
    //do somehting with the Bmp 
    Image1.Picture.Assign(Bmp); 
end; 
+0

इसके लिए धन्यवाद। क्या दूसरी बिटमैप की आवश्यकता के बिना इसे पूरा करने का कोई आसान तरीका है? उसी तरह डेल्फी में 'मूव' रूटीन ओवरलैपिंग स्रोत और गंतव्य को संभालता है, क्या एक द्वि-आयामी समतुल्य है? – rossmcm

+0

आप TBitmap की scanline संपत्ति के साथ ले जाएँ इस्तेमाल कर सकते हैं लेकिन आप BitsPerPixel –

+0

के आधार पर पिक्सल के बाइट-आकार की गणना करने के लिए इस केवल एक बिटमैप का उपयोग करता है दूसरा विकल्प की जाँच करनी होगी। (के बाद से BitBlt आपरेशन के दौरान रास्टर डेटा को बरकरार रखता है, और बस एक स्मृति बरबाद करती है) से पहले ओपी अपने प्रश्न संपादित – RRUZ

4

मैं जानता हूँ कि आप अपने स्वीकार्य उत्तर पहले से ही है, लेकिन चूंकि मैंने अपना संस्करण लिखा है (जो जीडीआई कॉल के बजाय वीसीएल रैपर का उपयोग करता है), मैं इसे सिर्फ इसे फेंकने के बजाय यहां पोस्ट करूंगा।

procedure TForm1.FormClick(Sender: TObject); 
var 
    Source, Dest: TRect; 
begin 
    Source := Image1.Picture.Bitmap.Canvas.ClipRect; 
    { desired rectangle obtained by collapsing the original one by 2*2 times } 
    InflateRect(Source, -(Image1.Picture.Bitmap.Width div 4), -(Image1.Picture.Bitmap.Height div 4)); 
    Dest := Source; 
    OffsetRect(Dest, -Dest.Left, -Dest.Top); 
    { NB: raster data is preserved during the operation, so there is not need to have 2 bitmaps } 
    Image1.Picture.Bitmap.Canvas.CopyRect(Dest, Image1.Picture.Bitmap.Canvas, Source); 
    { and finally "truncate" the canvas } 
    Image1.Picture.Bitmap.Width := Dest.Right; 
    Image1.Picture.Bitmap.Height := Dest.Bottom; 
end; 
संबंधित मुद्दे