C#中保存Gif文件设置透明无效果

C#中保存Gif文件设置透明无效果在C#中使用Graphics.Clear(Color.Transparent)生成gif格式透明文件时,设置透明不起作用。使用Bitmap.MakeTransparent方法同样也不能使gif文件透明。这两个问题也是微软的设计使然,和gif文件格式有关系。如果要在c#中编程实现透明色,必须另写代码,下面是一位老外的代码/// <summary>/// Make the i…

大家好,又见面了,我是你们的朋友全栈君。

在C#中使用Graphics.Clear(Color.Transparent)生成gif格式透明文件时,设置透明不起作用。使用Bitmap.MakeTransparent 方法同样也不能使gif文件透明。这两个问题也是微软的设计使然,和gif文件格式有关系。

如果要在c#中编程实现透明色,必须另写代码,下面是一位老外的代码

///
 
<summary>


///
 Make the image transparent. 

///
 The input is the color which you want to make transparent.

///
 
</summary>


///
 
<param name=”color”>
The color to make transparent.
</param>


///
 
<param name=”bitmap”>
The bitmap to make transparent.
</param>


///
 
<returns>
New memory stream containing transparent background gif.
</returns>


public
 Bitmap MakeTransparentGif(Bitmap bitmap, Color color)
{

    

byte
 R 
=
 color.R;
    

byte
 G 
=
 color.G;
    

byte
 B 
=
 color.B;

    MemoryStream fin 
=
 
new
 MemoryStream();
    bitmap.Save(fin, System.Drawing.Imaging.ImageFormat.Gif);

    MemoryStream fout 
=
 
new
 MemoryStream((
int
)fin.Length);
    

int
 count 
=
 
0
;
    

byte
[] buf 
=
 
new
 
byte
[
256
];
    

byte
 transparentIdx 
=
 
0
;
    fin.Seek(

0
, SeekOrigin.Begin);
    

//
header


    count 
=
 fin.Read(buf, 
0
, 
13
);
    

if
 ((buf[
0
] 
!=
 
71
) 
||
 (buf[
1
] 
!=
 
73
) 
||
 (buf[
2
] 
!=
 
70
)) 
return
 
null
; 
//
GIF



    fout.Write(buf, 

0
, 
13
);

    
int
 i 
=
 
0
;
    

if
 ((buf[
10
] 
&
 
0x80
) 
>
 
0
)
    {

        i 

=
 
1
 
<<
 ((buf[
10
] 
&
 
7
) 
+
 
1
) 
==
 
256
 
?
 
256
 : 
0
;
    }

    
for
 (; i 
!=
 
0
; i
—
)
    {

        fin.Read(buf, 

0
, 
3
);
        

if
 ((buf[
0
] 
==
 R) 
&&
 (buf[
1
] 
==
 G) 
&&
 (buf[
2
] 
==
 B))
        {

            transparentIdx 

=
 (
byte
)(
256
 
–
 i);
        }
        fout.Write(buf, 

0
, 
3
);
    }

    
bool
 gcePresent 
=
 
false
;
    

while
 (
true
)
    {

        fin.Read(buf, 

0
, 
1
);
        fout.Write(buf, 

0
, 
1
);
        

if
 (buf[
0
] 
!=
 
0x21
) 
break
;
        fin.Read(buf, 

0
, 
1
);
        fout.Write(buf, 

0
, 
1
);
        gcePresent 

=
 (buf[
0
] 
==
 
0xf9
);
        

while
 (
true
)
        {

            fin.Read(buf, 

0
, 
1
);
            fout.Write(buf, 

0
, 
1
);
            

if
 (buf[
0
] 
==
 
0
) 
break
;
            count 

=
 buf[
0
];
            

if
 (fin.Read(buf, 
0
, count) 
!=
 count) 
return
 
null
;
            

if
 (gcePresent)
            {

                

if
 (count 
==
 
4
)
                {

                    buf[

0
] 
|=
 
0x01
;
                    buf[

3
] 
=
 transparentIdx;
                }
            }
            fout.Write(buf, 

0
, count);
        }
    }
    

while
 (count 
>
 
0
)
    {

        count 

=
 fin.Read(buf, 
0
, 
1
);
        fout.Write(buf, 

0
, 
1
);
    }
    fin.Close();
    fout.Flush();

    
return
 
new
 Bitmap(fout);
}

在生成图片之后调用此方法,即可使gif显示透明色。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/162716.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • CFileDialog的使用方法简单介绍

    CFileDialog的使用方法简单介绍

    2021年12月10日
  • 连接查询和子查询哪个效率高

    连接查询和子查询哪个效率高需要进行多表查询的情况下,用连接查询和子查询哪个效率高?1、什么是子查询?举个简单的例子,那么子查询有什么优劣呢?子查询(内查询)在主查询之前一次执行完成。子查询的结果被主查询(外查询)使用。可以用一个子查询替代上边的的表名。子查询,将查询操作嵌套在另一个查询操作中。先执行子查询,再执行外查询注:在查询时基于未知的值时,应使用子查询子查询可以返回多个结果/单个结果,结果个数不同应该使用不同的操作符通过子查询不难看出,可以根据employee_id查到department_

    2022年5月29日
  • SMTP协议介绍_介绍给别人怎么写合同

    SMTP协议介绍_介绍给别人怎么写合同1、SMTP介绍基本概念SMTP(SimpleMailTransferProtocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP协议属于TCP/IP协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。通过SMTP协议所指定的服务器,就可以把E-mail寄到收信人的服务器上了,整个过程只要几分钟。SMTP服务器则

    2022年10月22日
  • sql 聚合函数有哪些

    sql 聚合函数有哪些聚合函数是对一组值执行计算并返回单一的值的函数,它经常与SELECT语句的GROUPBY子句一同使用,SQLSERVER中具体有哪些聚合函数呢?我们来一一看一下:1.AVG返回指定组中的平均值,空值被忽略。例:selectprd_no,avg(qty)fromsalesgroupbyprd_no2.COUNT返回指定组中项目的数量。例…

    2022年6月21日
  • window查找被占用端口[通俗易懂]

    window查找被占用端口[通俗易懂]1.cmd查询使用的端口号是否被占用:netstat-aon|findstr”8082″按回车显示占用8088端口对应的程序的PID号;2.根据PID号找到对应的程序:继续输入命令:tasklist|findstr”3850″按回车后显示出占用该端口的程序;3.按快捷键“Ctrl+Shift+Esc”调出Windows任务管理器,根据PID/程序对应名称结束该程序进程即可。4.重新编译项目即可。…

    2022年7月27日
  • cocos2d-x精灵移动的方法

    cocos2d-x精灵移动的方法

    2021年11月30日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号