cb200005rh_f.asp.htm

来自「C++builder学习资料C++builder」· HTM 代码 · 共 956 行 · 第 1/3 页

HTM
956
字号
<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bmp-&gt;Canvas-&gt;Pixels[x][y] =</span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ShadeOfGray(bmp-&gt;Canvas-&gt;Pixels[x][y], Brightness); </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b> if</b>   

(Dest) </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dest-&gt;Assign(bmp); </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b> else</b>   

<b>if</b> (SourceAsBitmap) </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SourceAsBitmap-&gt;Assign(bmp); </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;} </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<b> __finally</b></span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;{ </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b> delete</b>   

bmp; </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b> delete</b>   

mask; </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;} </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;} </span></p>   

   

<p class=Code><span class=Code>}</span></p>   

   

<p class=Captions><b>Figure   

4: </b>Code for the <i>GrayScale</i>   

function. </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=BodyText> <i>GrayScale</i> accepts an image in any supported   

graphic format. If the source image isn't a bitmap, then a destination bitmap   

must be supplied. The resulting grayscaled image will always be a bitmap, no   

matter what type of image is passed in as the source. If a destination bitmap   

is supplied, the grayscaled bitmap will be assigned to it. If not, then the grayscaled   

bitmap will be copied back into the source image. During the grayscale process,   

the image may be lightened or darkened using the <i>Brightness</i> parameter. </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=BodyText> You may   

have noticed the reference to the <i>Graphics::TBitmap</i> data type in the   

source code in Figure 4. The compiler will encounter two different <i   

style='mso-bidi-font-style:normal'>TBitmap</i> data types. If we don't specify   

a qualifier, an error will occur stating that there's an ambiguity. The <i   

style='mso-bidi-font-style:normal'>TBitmap</i> we want is defined in the   

Graphics unit, and the other one is in the Windows unit. </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=BodyText> Two   

local bitmaps are used to encapsulate the process: <i>bmp</i> holds a copy of the source and will be processed in place; <i>mask</i>   

holds a copy of <i>bmp</i>, which is turned   

into a monochrome mask using the <i>Mask</i> method. </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=BodyText> The   

logic can be separated into five primary steps: </p>   

   

<p class=BodyText> 1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   

Ensure   

there is a place to put the processed bitmap. </p>   

   

<p class=BodyText> 2) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   

Copy   

the source image to a local bitmap. </p>   

   

<p class=BodyText> 3) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   

Generate   

a mask from the local bitmap. </p>   

   

<p class=BodyText> 4) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   

For   

every pixel in the local bitmap, check the mask. If the corresponding pixel in   

the mask is black, convert its color to a shade of gray in the local bitmap. </p>   

   

<p class=BodyText> 5) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   

Copy   

the local bitmap to the destination bitmap, if supplied, or back into the   

source. </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=BodyText> <b>Ensure   

there is a place to put the processed bitmap.</b> If you're unfamiliar with the <b>dynamic_cast </b>construct, then   

the code shown in Figure 5 may be confusing. </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=Code><span class=Code>Graphics::TBitmap   

* SourceAsBitmap =</span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;<b> dynamic_cast</b>&lt;Graphics::TBitmap*&gt;(Source); </span></p>   

   

<p class=Code><span class=Code>&nbsp; </span></p>   

   

<p class=Code><span class=Code><b>if</b>   

(Source &amp;&amp; (SourceAsBitmap || Dest)) </span></p>   

   

<p class=Code><span class=Code>{</span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;... </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;<b> try</b></span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;{ </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;... </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;} </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;<b> __finally</b></span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;{ </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<b> delete</b>   

bmp; </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<b> delete</b>   

mask; </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;} </span></p>   

   

<p class=Code><span class=Code>}</span></p>   

   

<p class=Captions><b>Figure   

5:</b> Placing the   

processed bitmap. </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=BodyText> This   

simply uses run-time type identification (RTTI) to determine whether an object   

is of a given type. In this case, <i>Source</i>   

is a <i>TGraphic</i>, but we don't know which kind. <i>TGraphic</i> is an abstract class from which <i>TBitmap</i>, <i>TIcon</i>, and <i   

style='mso-bidi-font-style:normal'>TMetaFile</i> descend. The local variable, <i   

style='mso-bidi-font-style:normal'>SourceAsBitmap</i>, will be assigned NULL unless <i>Source</i> is actually a <i>TBitmap</i>.   

This way we can test whether we should even process the image, because it would   

be a waste of processor cycles if there's no place to put the result. Note the   

use of the <b>try..finally</b> block to ensure our local variables are always   

properly destroyed. </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=BodyText> <b>Copy   

the source image to a local bitmap.</b> When copying one bitmap to another, we can simply call the <i>Assign</i>   

method: </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=Code><span class=Code>bmp-&gt;Assign(Source); </span></p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=BodyText> Because   

we don't know what kind of image <i>Source</i>   

is, however, we may need to do some extra work. The code in <i   

style='mso-bidi-font-style:normal'>CopyGraphicToBitmap</i> was initially a part   

of <i>GrayScale</i>, but it's useful in its   

own right (see Figure 6). </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=Code><span class=Code><b>void</b>   

CopyGraphicToBitmap(TGraphic *Source, </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;Graphics::TBitmap *Dest, TColor   

TransparentColor) </span></p>   

   

<p class=Code><span class=Code>{</span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;Graphics::TBitmap * SourceAsBmp =</span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<b> dynamic_cast</b>&lt;Graphics::TBitmap   

*&gt;(Source); </span></p>   

   

<p class=Code><span class=Code>&nbsp; </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;<b> if</b>   

(Source &amp;&amp; Dest) </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;{ </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<b> if</b>   

(SourceAsBmp) </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dest-&gt;Assign(Source); </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<b> else</b></span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;{ </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dest-&gt;Height = Source-&gt;Height; </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dest-&gt;Width = Source-&gt;Width; </span></p>   

   

<p class=Code><span class=Code>&nbsp; </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dest-&gt;Canvas-&gt;Brush-&gt;Color =   

TransparentColor; </span></p>   

   

<p class=Code><span class=Code>&nbsp; </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dest-&gt;Canvas-&gt;FillRect(Dest-&gt;Canvas-&gt;ClipRect); </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dest-&gt;Canvas-&gt;Draw(0, 0, Source); </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;} </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;} </span></p>   

   

<p class=Code><span class=Code>}</span></p>   

   

<p class=Captions><b>Figure   

6:</b> The <i>CopyGraphicToBitmap</i>   

function. </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=BodyText> The   

purpose of this function is to end up with a bitmap that preserves the   

transparency of the original image. If the source image is a bitmap, it can   

simply be assigned to the destination bitmap. The <i>Assign</i> method is introduced in <i>TPersistent</i>   

as a way of copying one object to another. For most persistent objects, only   

objects of the same type can be copied. This holds true for <i   

style='mso-bidi-font-style:normal'>TBitmap</i>, which will only accept another <i>TBitmap</i> in its <i>Assign</i>   

method. </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=BodyText> If the   

source image is not a bitmap, then we need to draw it onto the destination.   

This is done in three steps: </p>   

   

<p class=BodyText> 1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   

Ensure   

the copy is sized to match the source image. We're going to use the <i>Canvas</i>   

<i>Draw</i> method, which will only draw on the available surface area of the   

copy. </p>   

   

<p class=BodyText> 2) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   

Fill   

the copy with the <i>TransparentColor</i>. <i>ClipRect</i> returns the area on   

which any kind of drawing will have an effect. </p>   

   

<p class=BodyText> 3) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   

Draw   

the source image onto the copy. </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=BodyText> The   

important thing to remember as you look at this code is that icons and   

metafiles only draw the areas that are not transparent. If a background color   

isn't provided, it will likely be white. When the resulting bitmap is used in a   

context that requires transparency, white will likely be chosen as the   

transparent color. If the image itself uses white, those areas will wash out. </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=BodyText> <b>Generate   

a mask from the local bitmap.</b> This is pretty straightforward. First we copy the local bitmap   

into the mask bitmap. Then the <i>Mask</i> method uses a given color to convert   

from a color bitmap into a monochrome bitmap. <i>TransparentColor</i> will be the color we used to fill in the   

background if the source image isn't a bitmap: </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=Code><span class=Code>mask-&gt;Assign(bmp); </span></p>   

   

<p class=Code><span class=Code>mask-&gt;Mask(bmp-&gt;TransparentColor); </span></p>   

   

<p class=Code><span class=Code>&nbsp; </span></p>   

   

<p class=BodyText> Keep in   

mind that the <i>TransparentColor</i>   

property is retrieved from the lower-left pixel. Occasionally, an image may   

actually include that pixel as part of the drawing. This code doesn't handle   

that case. <i>TransparentColor</i> would   

have to be set to a fixed value. I'll leave that case as an exercise for you. </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=BodyText> <b>For   

every pixel in the local bitmap, check the mask. </b>The code below is the source for   

this step: </p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=Code><span class=Code><b>for</b> (<b   

style='mso-bidi-font-weight:normal'>int</b> y = 0; y &lt; bmp-&gt;Canvas-&gt;ClipRect.Bottom;   

y++)</span></p>   

   

<p class=Code><span class=Code>{</span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;<b> for</b>   

(<b>int</b> x = 0; x &lt;   

bmp-&gt;Canvas-&gt;ClipRect.Right; x++)</span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;{ </span></p>   

   

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<b> if</b>   

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?