标题:[译文]取得32位的图标
只看楼主
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
结帖率:66.67%
 问题点数:0 回复次数:22 
[译文]取得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
suyongtao
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:33
帖 子:8674
专家分:127
注 册:2004-11-6
得分:0 
怎么没有人顶呀,,,,,,,,,,,版主你怎么又少了一万多分呀,,,,,,,,,

面朝大海,春暖花开!
2005-04-11 08:32
yichen
Rank: 1
等 级:新手上路
帖 子:303
专家分:0
注 册:2005-3-9
得分:0 
楼主的文章挺深奥的
不过挺不错的![IMG]http://images.[/IMG]

衣带渐宽终不悔, 为伊消得人憔悴。 纸上得来终觉浅, 绝知此事要躬行。
2005-04-11 12:10
leifeng926
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2005-3-30
得分:0 
我很少看英文
尽管我知道它很有用
楼主你真行
2005-04-11 16:18
幻风幻云
Rank: 1
等 级:新手上路
帖 子:762
专家分:0
注 册:2005-1-14
得分:0 
好久没看英文了

2005-04-11 17:08
nighmore
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2005-4-5
得分:0 
水平有限.......随便翻译点

时代在进步,随着应用程序各方面的发展,最终用户希望得到更加让振奋的用户界面。除了视觉方面的美观,一个完好的用户还有其他很多的作用。良好的设计并使用优美的图标来表现你的程序也会给使用你的程序的最终用户带来更好的工作体验。这正是我发表这篇文章的目的。好,现在让我我们深入到技术方面。
我们在微软的很多产品中看到了他们所使用的那些漂亮的工具栏图标。它们有阴影,24位真彩,幻灯片等等。这些图片实际上是24位图象用了一种阿尔法估算的方法将他们转换成了32位格式的。(有异议)这种格式不仅允许使用透明的像素,也允许使用半透明的像素。这将使图像很好的容合在背景中,而不是你有时候所见到的一些劣制的24位图像。倘若你从未在你的应用程序中用过这样的图标或图像,你很快会发现这对你来说是一个出乎意料的挑战,事实上存在着某些你不克服的障碍。甚至于在框架(.net framework?)中也存在着一些bug会使你无法正常的显示你的图像。在这篇文章中我会试着解释如何来克服这些障碍,和如何使用我的ImageList类来解决问题。
从这点出发,我会谈到图标和图像,也会涉及到24位阿尔法估算混合图像。(不明白as just是什么意思)。
今儿就这样.....

2005-04-11 20:46
Kyo
Rank: 6Rank: 6
等 级:贵宾
威 望:23
帖 子:4536
专家分:1
注 册:2004-12-27
得分:0 
8楼的真厉害...顶...

晕~我怎么灌水灌到这里来了...我先下载来看看...不保证会翻译的...

等我回帖吧...

2005-04-11 22:19
Kyo
Rank: 6Rank: 6
等 级:贵宾
威 望:23
帖 子:4536
专家分:1
注 册:2004-12-27
得分:0 

通过Nard M控制增加并且使用32位阿尔法混合图像和图标到图像目录

文章关于增加阿尔法混合图像到图像目录控制并且使用它们有关元件作了介绍 随着时间的推移,应用逐步发展,最终用户希望得到更加富有活力的用户界面。不仅是视觉上的请求,一个好的用户界面还有其他功能,图象更好的设计和使用不仅让你的应用突出,更会给最终用户带来更好的工作体验。这就是我决定发表本文的理由,现在,让我们深入到技术方面来. 我们在微软公司的很多产品中看到了他们所使用的那些漂亮的工具栏图标。它们包括阴影,24位真彩,幻灯片等等,这些图片实际上是24位图象用了一种阿尔法估算的方法将他们转换成了32位格式的。这个格式不但允许使用透明的像素,也允许使用半透明的像素。这将使图像很好的容合在背景中,而不是你有时候所见到的一些劣制的24位透明图像。如果你曾经应用过这样的图标或图像,你很快会发现这对你来说是一个出乎意料的挑战,事实上存在着某些你未克服的一些障碍.更不用说在阻止你正确地展示这样的图像的框架里存在的一个缺陷,在这篇文章里,我将试着解释如何克服这些障碍,以及怎样使用我的图像目录控制来解决问题。从这一时刻起, 我将称图象和图标为图像以及与32位阿尔法混合图像的参照.如上所述的缺陷,我相信,在于那目录元件本身.如果你设法使用images.add()的方法增加一32位图像到图像目录控制中,或设法使用Visual Studio IDE添加图像,以那未加工的格式的那图像文件为基础,你就会发现阿尔法估算的方法变成损坏的或丢失的。,,,,,,,,,,,,, 太晕了...待续...因为我没有学过C#,所以我也不知"ImageList"翻译成"图像目录"对不对... 如果楼主觉得可以这样翻译,我才想再翻译下去...不然会误人子弟的...


2005-04-12 04:27
幻风幻云
Rank: 1
等 级:新手上路
帖 子:762
专家分:0
注 册:2005-1-14
得分:0 
不错
8楼 10的兄弟继续

2005-04-12 10:02



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




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

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