2012-05-01 10 views
5

मैं article on Embarcadero के अनुसार बिटमैप की स्कैनलाइन तक पहुंचने का प्रयास कर रहा हूं।TBitmap की स्कैनलाइन पहुंच को सही ढंग से कैसे कार्यान्वित करें?

for y := 0 to n do 
begin 
    line := bitmap.scanline [y]; 
    for x := 0 to n do line [x] := value; 

जैसे स्कैनलाइन का उपयोग करना मैंने पहले लागू किया है। मैंने देखा कि स्कैनलाइन तक पहुंचने में अपेक्षाकृत अधिक समय लगता है और ऊपर वर्णित आलेख उस पर समाधान प्रदान करता है। मैं इसे सही ढंग से लागू करने में सक्षम नहीं हूं। मेरा कोड है:

unit SCTester; 

interface 

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    ExtCtrls; 

type 
    TRGBQuad = packed record 
     b: uInt8; 
     g: uInt8; 
     r: uInt8; 
     alpha: uInt8; 
    end; // Record: TQuad // 

// Override the definitions in Graphics.pas 
    TRGBQuadArray = packed array [0..MaxInt div SizeOf (TRGBQuad) - 1] of TRGBQuad; 
    PRGBQuadArray = ^TRGBQuadArray; 

    TForm1 = class(TForm) 
    Image: TImage; 
    procedure ImageDblClick(Sender: TObject); 
    end; 

var Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.ImageDblClick(Sender: TObject); 
var Bitmap: TBitmap; 
    q: TRGBQuad; 
    x, y: NativeInt; 
    FirstLine: PRGBQuadArray; 
    idx: NativeInt; 
    LineLength: NativeInt; 
begin 
    q.r := 0; q.g := 0; 
    Bitmap := TBitmap.Create; 
    Bitmap.Height := Image.Height; 
    Bitmap.Width := Image.Width; 
    Bitmap.PixelFormat := pf32Bit; 
    FirstLine := Bitmap.ScanLine [0]; 
    LineLength := (NativeInt (Bitmap.Scanline [1]) - NativeInt (FirstLine)) div SizeOf (TRGBQuad); 
    try 
     for y := Bitmap.Height - 1 downto 0 do 
     begin 
     for x := 0 to Bitmap.Width - 1 do 
     begin 
      q.b := (x xor y) mod 255; 
      idx := y * LineLength + x; 
      FirstLine [idx] := q; 
     end; // for 
     end; // for 
     Image.Picture.Assign (Bitmap); 
    finally 
     Bitmap.Free; 
    end; // try..finally 
end; 

end. 

और y = 1 और x = 0 होने पर मुझे हमेशा अवैध पहुंच मिलती है। लाइन लम्बाई ऋणात्मक (बिटमैप की चौड़ाई) है, लेकिन इसकी अपेक्षा की जा सकती है। मैं क्या गलत कर रहा हूं?

संपादित करें: ऊपर दिए गए कोड को अब तक संसाधित टिप्पणियों को प्रतिबिंबित करने के लिए बदला गया है।

+2

'' idx' NativeInt' के रूप में घोषित किया जाना चाहिए, तो अपने कोड 64 में रूप में अच्छी तरह से इस्तेमाल किया जा सकता है। 'लाइन लम्बाई' नकारात्मक नहीं होना चाहिए (इसलिए अवैध पहुंच)। मेरा निष्कर्ष यह है कि आप इस कोड को 64 बिट मोड में चला रहे हैं। –

+0

@LURD, मेरे विचार बिल्कुल - और प्रत्येक LongInt (...) को मूल UInt (...) – kobik

+0

@LURD रेखा लम्बाई नकारात्मक (और आमतौर पर नकारात्मक) हो सकती है, यह कोई समस्या नहीं है जो एवी का कारण बनती है। – kludg

उत्तर

5

किसी भी नकारात्मक सूचकांक का उपयोग करने की नहीं, मैं क्या करना होगा

procedure TForm1.Button1Click(Sender: TObject); 
var Bitmap: TBitmap; 
    q: TRGBQuad; 
    x, y: LongInt; 
    line{, FirstLine}: PRGBQuadArray; 
    idx: NativeInt; 
    LastLine: PRGBQuadArray; 
    LineLength: NativeInt; 
begin 
    q.r := 0; q.g := 0; 
    Bitmap := TBitmap.Create; 
    Bitmap.Height := Image.Height; 
    Bitmap.Width := Image.Width; 
    Bitmap.PixelFormat := pf32Bit; 

    LastLine := Bitmap.ScanLine[Bitmap.Height - 1]; 
    LineLength := (NativeInt(Bitmap.Scanline[Bitmap.Height - 2]) - NativeInt(Lastline)) div SizeOf(TRGBQuad); 
    try 
     for y := 0 to Bitmap.Height - 1 do 
     begin 
     for x := 0 to Bitmap.Width - 1 do 
     begin 
      q.b := (x xor y) mod 255; 
      idx := y * LineLength + x; 
      LastLine [idx] := q; 
     end; // for 
     end; // for 
     Image.Picture.Assign (Bitmap); 
    finally 
     Bitmap.Free; 
    end; // try..finally 
end; 
+0

यह काम करता है! आपको बहुत - बहुत धन्यवाद! नकारात्मक संख्याओं से बचने के लिए यह वास्तव में एक अच्छा तरीका है। इससे मुझे अपने बिटमैप्स को और भी तेज करने में मदद मिलेगी। – Arnold

+0

@ अर्नोल्ड - आपका स्वागत है! .. यह सत्यापित करना न भूलें कि आपके पास नीचे-नीचे बिटमैप है। –

+1

बिल्कुल! स्कैनलाइन के बारे में लेखों में मैंने जो पढ़ा है वह यह है कि स्कैनलाइन 'आमतौर पर' ऊपर से नीचे तक ऑर्डर की जाती है, इसलिए ऋणात्मक रेखा की लंबाई उत्पन्न होती है। किसी को पता होना चाहिए कि इस कोड को सभी मामलों में सही ढंग से चलाने के लिए किसी को सकारात्मक और नकारात्मक रेखा लंबाई के लिए स्पष्ट रूप से कोड करना होगा। संपादित करें: नकारात्मक या सकारात्मक रेखा लंबाई की भ्रमित शब्दावली से बचने के लिए मुझे नीचे-ऊपर और ऊपर-नीचे आदेशित बिटमैप्स का संदर्भ लेना चाहिए। – Arnold

1

लाइन लम्बाई बहुत सारे बिटमैप्स के लिए नकारात्मक है, क्योंकि वे अक्सर लाइनों को स्टोर करने के लिए नीचे-अप विधि का उपयोग करते हैं। MSDN: BITMAPINFOHEADER। तो इस तरह के मामले के लिए इस समाधान को संशोधित किया जाना चाहिए।

+0

आपका सुझाव क्या होगा? – Arnold

+0

मैं समझता हूं कि आपका क्या मतलब है, लेकिन मुझे लगता है कि 'लाइन लम्बाई नकारात्मक है' थोड़ा उलझन में है। मैं कहूंगा, नीचे-नीचे बिटमैप में पहली स्कैनलाइन मेमोरी लेआउट में आखिरी है। –

संबंधित मुद्दे