试试看Windows Live Writer的图片上传
ColorMatrix(色彩矩阵),是GDI+里用来调整图片色彩的矩阵。
什么是矩阵,说白了就是C#里的二维数组。
那么这个矩阵调整色彩的原理是什么,他是怎么来调整色彩的呢?这个要从线性代数里的矩阵相乘说起。
以下段落学过线性代数的读者可以跳过,这里我用自己的理解来描述下矩阵相乘的算法和结果。
在线性代数里,两个矩阵相乘,是这样计算的:
A矩阵乘以B矩阵,那么新生成一个矩阵C,C的第N行M列的元素等于A的N行和B的M列逐个元素相乘的和。新生成的矩阵行数等于A的行数,列数等于B的列数。
另外A和B需要满足,A的列数等于B的行数。这就是为了保证,A的每一行上每个元素都能B的每一列上每个元素都能相乘。
即A[m,n] X B[n,p] = C[m,p]
直观的描述下,有矩阵A[2,3]
{
1,2,3
4,5,6
}
和矩阵B[3,2]
{
7 , 8
9 , 10
11, 12
}
那么相乘后生成新矩阵C[2,2]
{
1*7+2*9+3*11,1*8+2*10+3*12
4*7+5*9+6*11,4*8+5*10+6*12
}
好了,矩阵的概念描述到此。以下就说说GDI+里的色彩矩阵。
在计算机里,一副图片可以看成是点的集合。虽然图片有宽和高的概念,看起来是二维的,其实在处理时我们完全可以把宽、高看成是图片的属性,和点无关,把图片的所有点看成是一维数组。
而点本身是红绿蓝的集合,现在计算图形中再加入一个Alpha值(表示透明度),那么就是4个属性的集合,这样一副图片就成了二维的数组了,也就是标准的矩阵了。
那么一副4个点的图片描述成矩阵就是P[4,4]
{
R1,G1,B1,A1
R2,G2,B2,A2
R3,G3,B3,A3
R4,G4,B4,A4
}
当我们把这个矩阵和另一个4X4的矩阵M
{
rr,gr,br,ar
rg,gg,bg,ag
rb,gb,bb,ab
ra,ga,ba,aa
}
相乘时,就会生成一个新的矩阵,新矩阵和原矩阵元素数量相同(不信可以用[5,4]、[6,4]矩阵和它相乘看看),并且新矩阵的每个元素,都发生了有趣的变化。我们来看看结果,新矩阵NP:
{
R1*rr+G1*rg+B1*rb+A1*ra,R1*gr+G1*gg+B1*gb+A1*ga,R1*br+G1*rg+B1*bb+A1*ba,R1*ar+G1*ag+B1*ab+A1*aa
......
......
......
}
可以看到,新矩阵第一行(也就是新的图片的第一个点)的R,G,B,A都等于原图片的第一个点的所有RGBA新的混合值了。也就说,通过矩阵相乘,可以在图片原来的基础上改变新图片RGBA各个分量的值。
同时也能看出来我为什么把M矩阵的各个元素这么命名:rr表示新生成的R分量中原R分量的比例,gr表示新生成G分量中原R分量的比例,br表示新生成的B分量中原R分量的比例。依此类推。
另外再说一点,那就是GDI+中ColorMatrix是个5X5的矩阵,而不是4X4的矩阵,为什么会多出1行和1列呢。
我们来看NP,他的第一个元素是R1*rr+G1*rg+B1*rb+A1*ra,看出什么了吗?那就是只能做3个元素的加法,而不能做负值运算,即如果我想做R1的反色运算(用255减去原来的值)就做不到了,所以GDI+在原来的基础上扩展了一维,虚拟的一维W,这样一个点就变成了R,G,B,A,W。这个多出来的W在平时是不存在的,只有在色彩矩阵运算时才起辅助作用,默认就是255。
我们看加了一维W后NP第一个元素的结果
R1*rr+G1*rg+B1*rb+A1*ra+W1*rw
这样,将rw设为1,rr设为-1,其他为0,那么结果就是255-R1,怎么样,反色运算能完成了。
这个世界上有很多种语言,为了在计算机上能表现这些语言,各个国家在UTF-8出现前都制订了各自不同的字符编码标准。各自并不兼容。直到UTF-8出现才算是有了个统一的编码标准(现在发现UTF-8也不能包括世界上所有文字),但是老标准还是在各自沿用。比如中国,GB2312的网页还是很多的^_^
那么怎么识别一个网页用的是什么编码呢?
一是网页或服务器直接报告浏览器,这个页面用的是什么编码。比如HTTP头的content-type属性,页面的charset属性。这个比较容易实现,只要检测这些属性就能知道用的是什么编码。
二是浏览器自动猜测。这个就类似人工智能了。比如有些网页没有写charset属性,那么我们看到页面显示乱码时,就会手动去选择页面编码,发现是乱码,就再换一个,直到显示正常为止。
今天这篇文章要说的就是第二个方法,用程序实现自动猜测页面或文件使用的字符集。
具体的原理就是基于统计学的字符特征分析,统计哪些字符是最常见的字符。这个工作Mozilla有专门的文章《A composite approach to language/encoding detection》说明。作者之一是Shanjian Li,中国北京人哦。
好了,具体的代码其实Mozilla已经用C++实现了,名字就叫UniversalCharDet,但是我翻遍了Internet也找不到.NET的实现类库,只有Google Code上有Java的翻译代码。没办法,自己翻译成C#的代码吧。
C#实现的源代码:http://code.google.com/p/nuniversalchardet/
PS1.顺便说一下标题,为什么叫比IE更准确,那是因为IE浏览器也自带字符集猜测功能,也有人实现了通过调用IE的接口来猜测字符集的功能类库(http://www.codeproject.com/KB/recipes/DetectEncoding.aspx),不过我试过,这个接口的准确率也不高,成功猜测几率远低于UniversalCharDet。
PS2.网上流传比较多的是Nchardet,这个是基于mozilla的老版本字符集猜测类chardet的C#实现。准确率也比较低,大致和IE的接口成功率差不多。
PS3.参考资料
juniversalchardet:http://code.google.com/p/juniversalchardet/ (java版代码在BIG5Prober和GB18030Prober类中有BUG,C#版已经修正)
原理参考: http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html
这该死的群贴图接收问题,早上好好的,中午就不行了。
修正了后,中午早上好了,下午又不行了……
这叫什么事啊
不知道这个功能有多少人期待,反正我是很想要这个功能的,因为看着群里人说话贴表情,自己看不见是很郁闷的事情。狠狠心找来LumaQQ的Java代码,自己一点点翻译成C#的加了进去。呵呵,在这里感谢Luma前辈和阿不同学的辛勤劳动,没有他们这个功能也出不来。
好了,不多说了,因为说也说不清……改动太多,代码也比较乱。提交给阿不同学了,只能辛苦他去整理了。
这里就放一个编译好的DLL吧,感兴趣的同学自己反编译看看实现的代码好了,真正的源代码等阿不再次更新吧~
嗯,说下怎么去下载自定义表情和图片:
在接收到群消息时,调用CustomFaceManage的AddClusterIM方法
1: client.CustomFaceManager.AddClusterIM(e.InPacket);
好了,就这么简单。那么有人问,图片保存到哪里去了呢?
这个是在App.config(编译后自动会更名成 程序名.exe.config)里可以配置的:
1: <?xml version="1.0" encoding="utf-8" ?>
2: <configuration>
3: <appSettings>
4: <add key="CustomFaceDir" value="D:\LumaQQ.NET\Faces\CustomFaceRecv" />
5: <add key="ImageDir" value="D:\LumaQQ.NET\Faces\Image" />
6: </appSettings>
7: </configuration>
如果不配置,默认放在程序所在目录的CustomFaceDir和imageDir里面。
好了,使用就这么简单~
点击下载LumaQQ.NET.rar
之前我写了一篇关于怎么在LumaQQ.NET里发送超长群消息的文章,经过自己的试验,是成功的。
但是之后我在实际应用中,发现有一段消息怎么也发送不出去,我觉得很奇怪,难道是我的程序有问题?
而且同样的消息,我用私聊也能发出去,这更让我以为是发送长消息的代码有问题……
于是我尝试了过滤回车,换行,查找非法字符等等方法,仍然一无所获……
然后我尝试截获收到的消息包,发现竟然只能收到第一段消息,而第二段根本收不到!这就难怪了,因为消息包不完整,自然不会显示出来。
这是怎么回事?为什么第二段消息收不到?我明明发送出去了,也没有收到超时的提示?在绝望中我想到了一点,会不会是腾讯因为消息中有什么敏感词汇将消息过滤了?
于是我将消息一点点的拆开发送,终于发现,这段消息里有两个汉字的组合是发不出去的,而且很神奇的是,不仅连在一起发不出去,在他们之间加上空格,换行,数字,字母依然是发不出去的,只有加上汉字才能发送成功。
好吧,这篇文章主要要表示的不是谴责腾讯干涉言论自由,这个错不再腾讯,责任在谁大家心知肚明;而是提醒下大家,使用LumaQQ.NET发消息失败时,不要将目光局限于是不是代码的问题,而是有可能问题出在其他外界因素上。
摘要: QQ群有两个ID,内部ID和外部ID。外部ID就是我们平时常见的ID,搜索啊,查看啊,都是这个ID。 而内部ID就不常见了,应该说用QQ的人是从来不知道还有这个ID的。但是,这个ID是这篇文章的重点。因为发群信息必须用到这个I...
阅读全文
摘要: 之前我们修改了LumaQQ.NET,让他能发送超长消息了。现在我们再来看看,怎么让其支持发送群超长消息。 可能有人说,这个简单,我照着发送普通消息的方法写一个发送群的不是一样吗? ...
阅读全文
哈哈,前两天从公司包了两个波利抱枕回家,好可爱啊~~