मुझे वास्तव में 32 बिट आरजीबीए प्रारूप में मनमानी आकार के टीबीटमैप को पूरी तरह से पारदर्शी (और अन्यथा खाली/खाली) बनाने में सक्षम होने की आवश्यकता है। कई बार। लाज़र टीबीटमैप में इस तरह के बिटमैप को लोड करने में सक्षम है और इसे लोड करने के बाद, आप स्कैनलाइन के साथ इसका उपयोग कर सकते हैं और आरजीबीए प्रारूप का उपयोग नहीं कर रहे हैं। लेकिन जब आप टीबीटमैप स्वयं बनाते हैं तो यह काम नहीं करता है। पिक्सेल प्रारूप पूरी तरह से अनदेखा प्रतीत होता है। तो मैंने जो किया वह बॉक्स से बाहर है, और सरल है, कि यह लगभग आश्चर्यजनक (!) है। लेकिन यह व्यावहारिक है, बहुत अच्छा काम करता है, और एलसीएल और किसी तीसरे पक्ष के पुस्तकालयों से पूरी तरह से स्वतंत्र है। ग्राफिक्स यूनिट पर भी निर्भर नहीं है, क्योंकि यह वास्तविक 32 बिट आरजीबीए बीएमपी फ़ाइल उत्पन्न करता है (मैं इसे टीएममोरीस्ट्रीम में उत्पन्न करता हूं, आप अलग-अलग उत्पन्न कर सकते हैं)। फिर एक बार आपके पास यह हो जाने के बाद, आपके कोड में कहीं और आप इसे TBitmap.LoadFrom स्रोत या TPicture.LoadFrom स्रोत का उपयोग करके लोड कर सकते हैं।
पृष्ठभूमि कहानी मैं शुरू में यहां बताए अनुसार ठीक से प्रारूपित बीएमपी फ़ाइल स्वरूप निम्नलिखित उत्पन्न करने के लिए चाहता था: http://www.fileformat.info/format/bmp/egff.htm लेकिन वहाँ बीएमपी प्रारूप के कुछ वेरिएंट थे, और मैं स्पष्ट नहीं था जो एक पर मैं पालन करने वाला था । तो मैंने एक रिवर्स इंजीनियरिंग दृष्टिकोण के साथ जाने का फैसला किया, लेकिन स्वरूप विवरण ने मुझे बाद में मदद की। मैंने एक खाली 1x1 पिक्सेल 32 आरजीबीए बीएमपी फ़ाइल बनाने के लिए एक ग्राफिकल संपादक (मैंने जीआईएमपी का उपयोग किया) का उपयोग किया, और इसे अल्फा 1 पी.बीएमपी कहा, इसमें केवल पारदर्शिता नहीं थी। फिर मैंने कैनवास को 10x10 पिक्सेल में बदल दिया, और अल्फा 10 पी के रूप में सहेजा।बीएमपी फ़ाइल। फिर मैंने दो फाइलों की तुलना की: compating two bmp files in vbindiff on Ubuntu तो मुझे पता चला कि केवल अंतर ही जोड़े गए पिक्सल थे (प्रत्येक एक 4 बाइट्स सभी शून्यों आरजीबीए था), और हेडर में कुछ अन्य बाइट्स थे। मैंने साझा किए गए लिंक पर प्रारूप प्रलेखन के कारण, मुझे पता चला कि ये थे: FileSize
(बाइट्स में), BitmapWidth
(पिक्सल में), BitmapHeight
(पिक्सल में) और BitmapDataSize
(बाइट्स में)। अंतिम एक BitmapWidth*BitmapHeight*4
था, क्योंकि आरजीबीए में प्रत्येक पिक्सेल 4 बाइट्स है। तो अब, मैं अल्फा 1p.bmp फ़ाइलों के अंदर देखे गए बाइट्स के पूरे अनुक्रम को उत्पन्न कर सकता हूं, अंत से 4 बाइट घटाएं (BitmapData
का पहला), फिर प्रत्येक पिक्सेल के लिए आरजीबीए डेटा के 4 बाइट्स (सभी शून्य) जोड़ें बीएमपी मैं उत्पन्न करना चाहता हूं, फिर प्रारंभिक अनुक्रम पर वापस आएं और परिवर्तनीय भागों को अद्यतन करें: फ़ाइल आकार, चौड़ाई, ऊंचाई और बीएमपी डेटा आकार। और यह बेकार ढंग से काम करता है! मुझे बस बिगइंडियन के लिए परीक्षण जोड़ना पड़ा और लिखने से पहले शब्द और शब्द संख्या को स्वैप करना होगा। बिगएंडियन में काम कर रहे एआरएम मंचों पर यह मुद्दा बन जाएगा।
कोड
const
C_BLANK_ALPHA_BMP32_PREFIX : array[0..137]of byte
= ($42, $4D, $00, $00, $00, $00, $00, $00, $00, $00, $8A, $00, $00, $00, $7C, $00,
$00, $00, $0A, $00, $00, $00, $0A, $00, $00, $00, $01, $00, $20, $00, $03, $00,
$00, $00, $90, $01, $00, $00, $13, $0B, $00, $00, $13, $0B, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $FF, $00, $00, $FF, $00, $00, $FF,
$00, $00, $FF, $00, $00, $00, $42, $47, $52, $73, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $02, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00);
(...)
Function RenderEmptyAlphaBitmap(AWidth,AHeight: integer): TMemoryStream;
var
buf : array[1..4096]of byte;
i,p : int64;
w : word;
dw : dword;
BE : Boolean;
begin
buf[low(buf)] := $00; //this is jyst to prevent compiler warning about not initializing buf variable
Result := TMemoryStream.Create;
if(AWidth <1)then AWidth := 1;
if(AHeight<1)then AHeight := 1;
//Write File Header:
Result.Write(C_BLANK_ALPHA_BMP32_PREFIX, SizeOf(C_BLANK_ALPHA_BMP32_PREFIX));
//Now start writing the pixels:
FillChar(buf[Low(buf)],Length(buf),$00);
p := Result.Position;
Result.Size := Result.Size+int64(AWidth)*int64(AHeight)*4;
Result.Position := p;
i := int64(AWidth)*int64(AHeight)*4; //4 because RGBA has 4 bytes
while(i>0)do
begin
if(i>Length(buf))
then w := Length(buf)
else w := i;
Result.Write(buf[Low(buf)], w);
dec(i,w);
end;
//Go back to the original header and update FileSize, Width, Height, and offset fields:
BE := IsBigEndian;
Result.Position := 2; dw := Result.Size;
if BE then SwapEndian(dw); Result.Write(dw, SizeOf(dw));
Result.Position := 18; dw := AWidth;
if BE then SwapEndian(dw); Result.Write(dw, SizeOf(dw));
Result.Position := 22; dw := AHeight;
if BE then SwapEndian(dw); Result.Write(dw, SizeOf(dw));
Result.Position := 34; dw := AWidth*AHeight*4;
if BE then SwapEndian(dw); Result.Write(dw, SizeOf(dw));
//Done:
Result.Position := 0;
end;
सूचना कैसे C_BLANK_ALPHA_BMP32_PREFIX
निरंतर मूल रूप से मेरी नमूना alpha1p.bmp फ़ाइल से बाइट क्रम की प्रति, शून्य से पिछले 4 बाइट्स, जो RGBA पिक्सेल थे। : डी
इसके अलावा, मैं IsBigEndian
समारोह जो इस प्रकार है उपयोग कर रहा हूँ:
Function IsBigEndian: Boolean;
type
Q = record case Boolean of
True : (i: Integer);
False : (p: array[1..4] of Byte);
end;
var
x : ^Q;
begin
New(x);
x^.i := 5;
Result := (x^.p[4]=5);
Dispose(x);
end;
यह लाजर विकी से नकल है: http://wiki.freepascal.org/Writing_portable_code_regarding_the_processor_architecture आप इस भाग को छोड़ सकते हैं अगर आप BigEndian प्लेटफार्मों के साथ सौदा नहीं है, या आप एक कंपाइलर IFDEF निर्देश का उपयोग कर सकते हैं। बात यह है कि यदि आप {$IFDEF ENDIAN_BIG}
का उपयोग करते हैं तो यह संकलक चीजें होती है, जबकि फ़ंक्शन वास्तव में सिस्टम का परीक्षण करता है। यह लिंक विकी में समझाया गया है।
नमूना उपयोग
Procedure TForm1.Button1Click(Sender: TObject);
var
MS : TMemoryStream;
begin
MS := RenderEmptyAlphaBitmap(Image1.Width, Image1.Height);
try
if Assigned(MS)then Image1.Picture.LoadFromStream(MS);
//you can also MS.SaveToFile('my_file.bmp'); if you want
finally
FreeAndNil(MS);
end;
end;
अगर आप का पालन करें तो क्या होता है [इस] (http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Graphics_TBitmap_TransparentMode.html) उदाहरण ? –
क्या आप बस कुछ भी आकर्षित नहीं करना चाहते हैं? क्या आप एक पूर्ण पारदर्शी बिटमैप तैयार करना चाहते हैं? – Shambhala
@ शमबाला नहीं, मैं सिर्फ एक (छोटा) हिस्सा आकर्षित करना चाहता हूं। – NGLN