标题:[译文]取得32位的图标
取消只看楼主
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
结帖率:66.67%
 问题点数:0 回复次数:4 
[译文]取得32位的图标

最后译文在第3页第21楼,感谢nighmore朋友的全力帮助,还有Kyo斑竹。 斑竹我由于项目需要,要看以下这篇文章,请求朋友们帮忙翻译一下。 虽然出于我个人的理由需要大家帮忙,但是我保证这篇文章是一项非常有用的算法技术。 大家翻译后必定有很大帮助,至少比光看语法好得多。 我说一下翻译的要求,除代码和注释以外,全部都希望大家帮忙翻译, 我本人也懂英语,不过就没时间翻译全文,希望有心人帮忙,不用全部翻译, 就大家看得感兴趣的段落哪怕是三两句,看得懂的就帮忙翻译出来, 以跟帖的形式,大家几句几句地凑起来,就可以成为完整的译文, 我以斑竹的身份加上10000论坛币请求大家贡献一点点时间,就算只是翻译1~2句, 我也感激,也会加分,呵呵……谢谢! PS:我有空也会几句几句地翻译出来。 Adding and using 32 bit alphablended images and icons to the imagelist control By Narb M An article on adding alphablended images to an imagelist control and using them on components. Introduction As time goes on and applications evolve, the end user expects a richer and more vibrant user interface. Not only is it visually appealing, a nice user interface also serves as a function. Better design and use of icons to represent tasks will not only make your application stand out but will also give the end user a better experience working with your applications. This is the reason why I decided to publish this article. Now, let's jump to the technical aspects... We've all seen those nice toolbar icons Microsoft (c) uses in their products. They include shadows, 24 bit true colors, transparencies etc. These images are actually 24 bit images that contain an alpha channel which makes them 32 bit format. This format not only allows transparent pixels, but semi-transparent pixels as well. This allows images to blend in with their background nicely without the "jaggedness" you sometimes see with regular 24 bit transparent images. If you have ever tried using such icons or images in your applications, you have quickly found out that it's somewhat more of a challenge than you expected, and in fact there are some obstacles to overcome. Not to mention a bug that exists in the framework that will prevent you from displaying such images properly. In this article, I will try to explain what is needed to overcome these obstacles and also how to use my ImageList class to fix the problem. From this point on, I will refer to both icons and images as just images and also refer to 24 bit alpha blended images as just 32 bit images. The Problem The bug I mentioned above, I believe, exists in the ImageList component itself. If you try to add a 32 bit image using the Images.Add() method of the ImageList control, or try to add images using the Visual Studio IDE, you will find that the alpha channel becomes either corrupt or lost all together based on the raw format of the image file itself. An example of this would be to create a new Bitmap object and load a 32 bit image such as a .png file, using the Bitmap constructor like: Bitmap bm = new Bitmap( file );, and then using the ImageList. Add method to add the bitmap object to the ImageList. Even though the bitmap's .IsAlphaFormat property is true, the image becomes corrupt in the process of adding to the ImageList control, and if you try to use these images on controls, you will find that they are displayed incorrectly. My belief is that the problem exists in the way the .Add() method extracts the alpha channel and copies it to the ImageList from a bitmap structure. The reason why I came to this conclusion was because supplying a handle to an image with the .Add() method seems to work. You will see I use this method for Icons (.ico files) since the Icon class has a .FromHandle method that returns a Windows icon. Now, if you try using these added images for your controls, you will find that since the alpha channel has become corrupt, the images contain solid black for the areas where alpha blending was to take place. In cases where you add PNG files with alpha channel, you will find that alpha blending does occur but contains a subtle color error in the areas where alpha blending was to take place. You can see a good example of this in the included image above by looking at the zoomed IE and MSN icon on the left. This might not be an eye catching thing for these 32x32 pixel icons but when you have 16x16 icons, the color error is very apparent. In conclusion, the ImageList control itself can hold 32 bit alpha blended images with no problems but the methods used to add those images are causing the corruption to occur. The Fix I have come up with a simple class with some static methods to perform the adding of 32 bit images to your ImageLists. The class Imagelist and its five methods allow you to add images correctly from various sources. These sources include an Image or Icon object, an external image file or icon file, an embedded image resource in your project, any external file icon or folder icon, and any file system extension icon. Each of these have examples and explanations below. Various methods are used for adding images from the different sources, but for the main part, Win32 API is used. When adding images from external files or from an Image object, basically what is done is a new bitmap is created using the CreateDIBSection() API call which resides in the gdi32.dll, and creates a bitmap object and returns a handle to the bitmap object in memory. Then the image is copied into this area in memory with correct formatting. The bitmap is then loaded into the ImageList using the ImageList_Add() call which takes a handle to an ImageList control and a handle to a bitmap object. When adding Icon objects or files, you can add them correctly by using the Icon object's .Handle property. Once the images are loaded into the ImageList control, you can use them normally for toolbars, listviews, etc. by assigning the indexer to a control. Also, all of its native methods hold and return correct values such as the .Count property. Before using the code First and foremost, your C# application and control properties must be setup correctly before the images are displayed properly. Let's go over these first before moving onto the usage of the class. You will see below that the Application.EnableVisualStyles() and Application.DoEvents() must be made before a .Run method. Another crucial property that must be set is the ImageList ColorDepth property, which must be set to ColorDepth.Depth32Bit. You can of course set this property using the Visual Studio IDE. Also keep in mind that alpha blended images are only supported in Windows XP+ and .NET Framework 1.1+. This code will have no effect on earlier versions of Windows. // // Enabling Visual Styles // static void Main() { // These two calls MUST be made before the // .Run method to enable 32bit icons to be used. Application.EnableVisualStyles(); Application.DoEvents(); // The color depth of the ImageList MUST be set // to 32bit before images can be added to the control. myImagelist.ColorDepth = ColorDepth.Depth32Bit; Application.Run(new Form1()); } Public Methods of the ImageList Class public sealed class Imagelist { public static void AddFromImage(Image sourceImage, ImageList destinationImagelist) {..} public static void AddFromImage(Icon sourceIcon, ImageList destinationImagelist) {..} public static void AddFromFile(string fileName, ImageList destinationImagelist) {..} public static void AddIconOfFile(string fileName, IconSize iconSize, bool selectedState, bool openState, bool linkOverlay, ImageList destinationImagelist) {..} public static void AddIconOfFile(string fileName, ImageList destinationImagelist) {..} public static void AddIconOfFileExt(string fileExtension, IconSize iconSize, bool selectedState, bool openState, bool linkOverlay , ImageList destinationImagelist) {..} public static void AddIconOfFileExt(string fileExtension, ImageList destinationImagelist) {..} public static void AddEmbeddedResource(string resourceName, ImageList destinationImagelist) {..} }

[此贴子已经被作者于2005-4-16 18:20:59编辑过]

搜索更多相关主题的帖子: 译文 图标 
2005-04-09 18:12
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
得分:0 

Now that those calls and properties have been made, we can move on to the usage of the static class methods....

Adding Image or Icon objects

//

// This example adds a 32bit alphablended image

// to myImagelist using the AddFromImage() method.

// This overloaded method accepts either

// an Image object or Icon object as its source.

//

Narbware.Imagelist.AddFromImage( Image.FromFile("image.png"),

myImagelist );

Bitmap myBitmap = new Bitmap( "image.png" );

Narbware.Imagelist.AddFromImage( myBitmap, myImagelist );

Icon myIcon = new Icon("icon.ico");

Narbware.Imagelist.AddFromImage( myIcon, myImagelist );

Adding images from embedded resources

The importance of this method is that you can use it to pre load images to the ImageList from an embedded resource. This means no external image files are needed when wanting preloaded images in your ImageList. This is because you cannot use the IDE to pre load images because that essentially uses the ImageList.Add() method. An important step when adding embedded resources is after you have added the image resource to your project, you must set its Build Action property to 'Embedded Resource'. Once that is done, the code below will add that resource to your ImageList.

//

// This example adds a 32bit alphablended image from

// an embedded resource to myImagelist

// using the AddEmbeddedResource() method.

//

Narbware.Imagelist.AddEmbeddedResource( "myApplicationName.image.png",

myImagelist ); // where image.png resides in the projects root

Adding images from external files

This method saves some time when wanting to add images from files that reside outside of your project's directory. Since you don't have to create an Image, load the file into the Image, then add it to the ImageList. Instead, you can just supply the path of the image you want to add.

//

// This example adds a 32bit alphablended image from an external

// file to myImagelist using the AddFromFile() method.

//

Narbware.Imagelist.AddFromFile( "c:\\blah\image.png", myImagelist );

Narbware.Imagelist.AddFromFile( "c:\\icons\icon.ico", myImagelist );

Extracting and adding file or folder icons

This method extracts file or folder icons and adds them to ImageList. This is a powerful method that the framework currently does not support and can be appreciated in any application dealing with the shell. This method has two overloads, a simple overload which, by default, will add a large sized icon to an ImageList, and a second overload which gives you the ability to format the icon you want to extract. For example, adding the selected state of the icon, or adding the icon with a link overlay, specifying the size of the icon you want to extract etc...

//

// This example extracts and adds 32bit alphablended icons

// from external files and folders

// to myImagelist using the AddIconOfFile() method.

//

// This short overload extracts and adds

// a largs icon (32x32) to and imagelist

Narbware.Imagelist.AddIconOfFile( "c:\\file.mpg",

myImagelist )

// adds the files icons, in this case the systems mpg icon

// This longer method gives you more

// options on the type of icon to extract

Narbware.Imagelist.AddIconOfFile( "c:\\file.mpg",

Narbware.IconSize.Small, false, false,

false, myImagelist );

// This adds a folder icon. It can also extract

// special folder icons such as My Music, My Pictures, etc...

Narbware.Imagelist.AddIconOfFile( "c:\mySpecialFolder",

Narbware.IconSize.Large, false, false,

false, myImagelist );

Extracting and adding file type icons (extensions)

This method is similar to the above AddIconOfFile() method, instead you supply the method with the extension of the icon you want to extract from the system. All the rules from the above method hold for this method. Examples below...

//

// This example extracts and adds 32bit alphablended file

// extension icons to myImagelist using the AddIconOfFileExt() method.

//

// adds a large sized icon associated with jpeg files.

Narbware.Imagelist.AddIconOfFileExt( "jpg", myImagelist );

Narbware.Imagelist.AddIconOfFileExt( "zip", Narbware.IconSize.Small,

false, false, false, myImagelist );

// adds a small sized zip file icon to the imagelist.

Points of Interest

Below is the private method used to add the 32 bit images to ImageLists. This is essentially the fix to the problem of the corrupt alpha channel. Note that a new Device Independent Bitmap (DIB) object is created with correct formatting based on the BITMAPINFO structure, and the desired bitmap is then copied to this location and added to our ImageList using Win32 API. The other overloaded Add() method is used to extract file icons which is done by creating and passing a SHFileInfo object and returning a handle to the file icon at which point it is added using the default ImageList's Images.Add(); method.

private static void Add( Bitmap bm, ImageList il )

{

IntPtr hBitmap, ppvBits;

BITMAPINFO bmi = new BITMAPINFO();

if ( bm.Size != il.ImageSize )

{

// resize the image to dimensions of imagelist before adding

bm = new Bitmap( bm, il.ImageSize.Width, il.ImageSize.Height );

}

bmi.biSize = 40; // Needed for RtlMoveMemory()

bmi.biBitCount = 32; // Number of bits

bmi.biPlanes = 1; // Number of planes

bmi.biWidth = bm.Width; // Width of our new bitmap

bmi.biHeight = bm.Height; // Height of our new bitmap

bm.RotateFlip( RotateFlipType.RotateNoneFlipY );

// Required due to the way bitmap is copied and read

hBitmap = CreateDIBSection( new IntPtr(0), bmi, 0,

out ppvBits, new IntPtr(0), 0 );

//create our new bitmap

BitmapData bitmapData = bm.LockBits( new Rectangle( 0, 0,

bm.Width, bm.Height ), ImageLockMode.ReadOnly,

PixelFormat.Format32bppArgb );

RtlMoveMemory( ppvBits, bitmapData.Scan0,

bm.Height * bitmapData.Stride );

// copies the bitmap

bm.UnlockBits( bitmapData );

ImageList_Add( il.Handle, hBitmap, new IntPtr(0) );

// adds the new bitmap to the imagelist control

}

Conclusion

By using the ImageList class and its methods of adding images from various sources, you are now be able to use 32 bit alpha blended images in your C# applications. Once the images have been added, you can continue to use the ImageList control as usual. If you feel there are incorrect or misleading information in this article, please feel free to point them out. I'm somewhat of a beginner to C#, so I might not have everything down yet. Also, any comments or suggestions would be appreciated. Thanks.

About Narb M

I'm a current student at California State University of Northridge majoring in computer science. My interests include working on high performance cars and bikes, doing webdesign work and of course, programming. I always enjoy a good challenge no matter what subject it's in.

Click here to view Narb M's online profile.

2005-04-09 18:12
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
得分:0 
感谢大家,我稍候会给分,楼上的实在是英雄!
2005-04-15 22:36
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
得分:0 
分已经送出,虽然论坛分暂时还不值钱,不过对nighmore朋友的英文水平深表敬佩,也非常感谢KYO斑竹。
2005-04-16 01:54
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
得分:0 
加精此帖,功劳归两位翻译者,非常感谢!
2005-04-16 18:18



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-15207-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.141576 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved