理财秘籍

bitmaporbitmapor

Vicky 0

今天给各位分享bitmap or的知识,其中也会对bitmapor进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录

postgresql和mysql的区别Android系统中Bitmap是否有调用recycle方法的必要性什么是BitmapAndroid Bitmap 与 Drawable之间的区别和转换如何空清空TBitmap图象postgresql和mysql的区别区别就是两者意思是不一样具体的不同如下

PostgreSQL是一种特性非常齐全的自由软件的对象-关系型数据库管理系统(ORDBMS),是以加州大学计算机系开发的POSTGRES,4.2版本为基础的对象关系型数据库管理系统。

MySQL是一个关系型数据库管理系统,由瑞典MySQLAB公司开发,属于Oracle旗下产品。MySQL是最流行的关系型数据库管理系统之一,在WEB应用方面,MySQL是最好的RDBMS(RelationalDatabaseManagementSystem,关系数据库管理系统)应用软件之一。MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。MySQL所使用的SQL语言是用于访问数据库的最常用标准化语言。MySQL软件采用了双授权政策,分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型和大型网站的开发都选择MySQL作为网站数据库。

Android系统中Bitmap是否有调用recycle方法的必要性1:Bitmap是否有调用recycle方法的必要性?

A:嵌入式系统总是格外注重空间的问题,不小心的话就会有OOM。但是应用层使用java的android平台有其天然的优势【java语言有自己的垃圾回收,android平台上各个application有自己的process自己的空间】。

无需调用bitmap的理由有:

a.垃圾回收会处理的;

b.当application关闭,process被杀掉,所有这个process占用的空间自然回归系统;

但是,如果你有点洁癖,或者有点理想主义,或者很有控制欲,或者很闲。。。bitmap的recycle函数的调用还是可以是有必要的,理

股市封盘什么意思啊

由有:

a.垃圾回收虽然好使,但是有可能的话,我们还是让它少干点活吧。垃圾回收有很大的未来不确定性,会加重未来未知时间点的loading,若有大量bitmap需要垃圾回收处理,那必然垃圾回收需要做的次数就更多也发生地更频繁,小心会造成ANR。但是,若是自己recycle,就可以可控制地分散处理了这些回收任务了。

b.若是launcher那样一直运行的application,它的process一直存在,memory问题还是多多注意下比较好。

Q2:When?

A:Timing的问题在这里很重要。早了就大事不好了,会有这样的Exception:

java.lang.RuntimeException,Canvas:tryingtousearecycledbitmap

android.graphics.Bitmap@44ebeee0,Canvas.java,955

So,怎样才可以保证不会早了呢?

关于图片显示,重要的时间点:

step1:设置进去的时间点;

Step2:画面画出来的时间点;

最保险最笨的做法,在新的图片设置进去以后再recycle掉老的图片,这样做的坏处在于,在某个时间段,你需要的空间是double的【新旧两套都在】;

如果你不偏向于那么做,又有时间,可以考虑后面一个时间点,除了setImage以及其它代码中显示调用那个bitmap的时候我们会检查bitmap,在acticvity变为visible的时候系统还是会去找之前设置进去的bitmap【即使你的onResume方法里面并没有提到去refreshUI,这件事情它也是会去做的,大概不然它就不知道这次该显示些什么了】。所以,在UI线程里面,在一个不可能被打断的方法里面,是先设置新的bitmap还是先recycle旧的图片是没有影响的。

譬如说mBitmap.recycle();

mBitmap=…..//设置

mImageView.setImage(mBitmap);

这样的代码是完全可以的。

后面这样的做法,最重要的就是确保:在UI线程【因为设置UI显示只能在UI主线程里】里面一个不可能被打断的方法里面。这个是为了确保在两者之间UI主线程不可能被打断,不可能刚好从invisible变成visible。

所以,特别小心两种东西:

1.多线程【个人觉得最好不要在其他线程里面调用UI用过的bitmap的recycle方法,多线程之间是很难保证时间顺序的,暂时没有想出一种在backgroundthread里面recycle的合理的方式】;

2.非及时发生的方法:譬如,发intent啊,发notify啊去通知UI主线程去做UI重新刷新并不能替代mImageView.setImage(mBitmap);这样的句子。完全有可能,你确实发了intent出去了,但是目标activity之一还没有做UI重新设置【Q:maybe没收到or收到但还是等待处理,不确定这两种可能是不是都有可能】,这个时候这个acitivity变成visible了,系统仍然试图找旧的图片,找不到了就会报exception了。

PS:java.lang.RuntimeException,Canvas:tryingtousearecycledbitmapandroid.graphics.Bitmap@44ebeee0,Canvas.java,955这样的exception可能也许你并不能够看到,默认的log里面好像只能看到uncaughtexception,第一次看到是在monkey的events.log里面,若你知道怎么打开相应手机这方面的logtrace应该也是可以看到的。

什么是Bitmapa)Bitmap如何做到多维交叉计算的?

Bit即比特,是目前计算机系统里边数据的最小单位,8个bit即为一个Byte。一个bit的值,或者是0,或者是1;也就是说一个bit能存储的最多信息是2。

Bitmap可以理解为通过一个bit数组来存储特定数据的一种数据结构;由于bit是数据的最小单位,所以这种数据结构往往是非常节省存储空间。比如一个公司有8个员工,现在需要记录公司的考勤记录,传统的方案是记录下每天正常考勤的员工的ID列表,比如2012-01-01:[1,2,3,4,5,6,7,8]。假如员工ID采用byte数据类型,则保存每天的考勤记录需要N个byte,其中N是当天考勤的总人数。另一种方案则是构造一个8bit(01110011)的数组,将这8个员工跟员工号分别映射到这8个位置,如果当天正常考勤了,则将对应的这个位置置为1,否则置为0;这样可以每天采用恒定的1个byte即可保存当天的考勤记录。

综上所述,Bitmap节省大量的存储空间,因此可以被一次性加载到内存中。再看其结构的另一个更重要的特点,它也显现出巨大威力:就是很方便通过位的运算(AND/OR/XOR/NOT),高效的对多个Bitmap数据进行处理,这点很重要,它直接的支持了多维交叉计算能力。比如上边的考勤的例子里,如果想知道哪个员工最近两天都没来,只要将昨天的Bitmap和今天的Bitmap做一个按位的“OR”计算,然后检查那些位置是0,就可以得到最近两天都没来的员工的数据了,比如:

Android Bitmap 与 Drawable之间的区别和转换Bitmap-称作位图,一般位图的文件格式后缀为bmp,当然编码器也有很多如RGB565、RGB888。作为一种逐像素的显示对象执行效率高,但是缺点也很明显存储效率低。我们理解为一种存储对象比较好。

Drawable-作为Android平下通用的图形对象,它可以装载常用格式的图像,比如GIF、PNG、JPG,当然也支持BMP,当然还提供一些高级的可视化对象,比如渐变、图形等。

AbitmapisaDrawable.ADrawableisnotnecessarilyabitmap.Likeallthumbsarefingersbutnotallfingersarethumbs.

Bitmap是Drawable.Drawable不一定是Bitmap.就像拇指是指头,但不是所有的指头都是拇指一样.

TheAPIdictates:API规定:

Thoughusuallynotvisibletotheapplication,Drawablesmaytakeavarietyofforms:尽管通常情况下对于应用是不可见的,Drawables可以采取很多形式:

Bitmap:thesimplestDrawable,aPNGorJPEGimage.Bitmap:简单化的Drawable,PNG或JPEG图像.

NinePatch:anextensiontothePNGformatallowsittospecify

informationabouthowtostretchitandplacethingsinsideofit.

Shape:containssimpledrawingcommandsinsteadofarawbitmap,allowingittoresizebetterinsomecases.

Layers:acompounddrawable,whichdrawsmultipleunderlyingdrawablesontopofeachother.

States:acompounddrawablethatselectsoneofasetofdrawablesbasedonitsstate.

Levels:acompounddrawablethatselectsoneofasetofdrawablesbasedonitslevel.

Scale:acompounddrawablewithasinglechilddrawable,whoseoverallsizeismodifiedbasedonthecurrentlevel.

如何空清空TBitmap图象由Delphi中的图像灰度化代码看基本图像处理

基础篇]

首先看一段实现24位色图像灰度化转换的代码

procedureGrayscale(constBitmap:TBitmap);

var

X:Integer;

Y:Integer;

R,G,B,Gray:Byte;

Color:TColor;

begin

forY:=0to(Bitmap.Height-1)do

begin

forX:=0to(Bitmap.Width-1)do

begin

Color:=Bitmap.Canvas.Pixels[X,Y];

R:=Colorand$FF;

G:=(Colorand$FF00)shr8;

B:=(Colorand$FF0000)shr16;

Gray:=Trunc(0.3*R+0.59*G+0.11*B);

Bitmap.Canvas.Pixels[X,Y]:=Grayshl16orGrayshl8orGray;

end

end

end;

{这段代码效率是非常低的,但可以方便我们理解同时一些问题}

Delphi的帮助中对TColor已经有了详细的描述,这可以方便我们理解上面的代码!

首先看:

R:=Colorand$FF;

G:=(Colorand$FF00)shr8;

B:=(Colorand$FF0000)shr16;

这是段常见的从TColor中提取三原色的代码,但它是什么意思呢?

首先应该知道and是与(.)运算,0.1=0,0.0=0,1.1=1,以取绿色为例:$FF00实际上就是$00FF00,它与一个TColor类型数按位进行与运算后,表示红色和绿色的位都变为了$00,而表示绿色的部分不变(0,1和1进行与运算值都不变),再右移8位,自然就获得了绿色值的8位表示!

再获得三原色的值后,就是计算灰度值,0.3*Red+0.59*Green+0.11*Blue这是求加权平均值的公式。(因为人眼对颜色的敏感度不同,所以权值不同,就像在pf16bit中用了6位表示绿色,其它两种颜色只用了5位,这问题以后另写文章说明)

然后就是像素颜色信息的写回,刚才是右移,现在自然就是左移,而或(+)运算就是(0+1=1,0+0=0,1+1=1),举个简单例子就是:($FFshl16=$FF0000)or($FFshl8=$FF00)or$FF=$FFFFFF,其实这里的或运算当然也可以用+代替。

虽然上面的代码实现了24位色图像的灰度化,但当图像比较大时,速度非常慢,为什么?查看相关VCL代码可知调用Bitmap.Canvas.Pixels获取,写入像素的颜色信息实际上是利用了APIGetPixel、SetPixel,这种方法是非常低效的!(唯一的好处是在进行一些和颜色无关的操作,如图像的旋转,翻转时不需要因为PixelFormat的不同而修改代码)所以应该换一种更高效的访问像素点数据的方法,如用APIGetDIBits、SetDIBits,但这种方法比较复杂,好在Delphi3以后版本的TBitmap中提供了Scanline。利用Scanline可以快速对像素进行访问!

还是以24位色(PixelFormats=pf24bit)为例,可改写为:

procedureGrayscale(constBitmap:TBitmap);

const

PixelCountMax=32768;

type

pRGBTripleArray=^TRGBTripleArray;

TRGBTripleArray=ARRAY[0..PixelCountMax-1]OFTRGBTriple;

var

Row:pRGBTripleArray;

X:Integer;

Y:Integer;

Gray:Byte;

begin

forY:=0to(Bitmap.Height-1)do

begin

Row:=Bitmap.ScanLine[Y];

forX:=0to(Bitmap.Width-1)do

begin

Gray:=Trunc(0.3*Row^[X].rgbtRed+0.59*Row^[X].rgbtGreen+0.11*Row^[X].rgbtBlue);

Row^[X].rgbtRed:=Gray;

Row^[X].rgbtGreen:=Gray;

Row^[X].rgbtBlue:=Gray;

end;

end;

end;

上面的例子用了一个TRGBTriple数组

PRGBTriple=^TRGBTriple;

tagRGBTRIPLE=packedrecord

rgbtBlue:Byte;

rgbtGreen:Byte;

rgbtRed:Byte;

end;

TRGBTriple=tagRGBTRIPLE;

这种方法会限制位图的大小,但一般不用理会,直接用TBitmap可处理不了那么大的位图

当然也可用指针的移动实现,实测结果这样更快~~~

procedureGrayscale(constBitmap:TBitmap);

var

X:Integer;

Y:Integer;

PRGB:pRGBTriple;

Gray:Byte;

begin

forY:=0to(Bitmap.Height-1)do

begin

PRGB:=Bitmap.ScanLine[Y];

forX:=0to(Bitmap.Width-1)

德阳建院各专业录取分数线

do

begin

Gray:=Trunc(0.3*PRGB^.rgbtRed+0.59*PRGB^.rgbtGreen+0.11*PRGB^.rgbtBlue);

PRGB^.rgbtRed:=Gray;

PRGB^.rgbtGreen:=Gray;

PRGB^.rgbtBlue:=Gray;

Inc(PRGB);

end;

end;

end;

[颜色篇]

在上面提到了,那灰度化代码只能适用于24位色(PixelFormats=pf24bit),为什么?看看记录类型tagRGBTRIPLE,正好24位,所以这样只能处理24位色图!

那怎么处理其他的位图呢?

先对这各种类型的位图做些简单的介绍~~~

pf1bit:

每个像素只需要用一位表示,如调色板定义的是黑白两种颜色(0为黑,1为白),这时只能用位操作访问像素信息!如定义

varP:PByte

forY:=0to(Bitmap.Height-1)do

begin

p:=Bitmap.ScanLine[Y];

forX:=0to(Bitmap.width-1)DIV8+1do

begin

p^:=1or2or4or8or16or32or64or128;

Inc(PRGB,3);

end;

end;

p^:=1or2or4or8or16or32or64or128;

这行代码什么意思呢?1=1(二进制),2=10(二进制),4=100(二进制),8=1000(二进制)...

结合上篇中解释了的或运算,很容易理解就以八个字位为单位,给其赋上颜色信息!

pf4bit:

和pf1bit位图一样,操作pf4bit位图也需要用位操作。

pf8bit:

可直接利用Byte、TByteArray,但用Scanline取的值表示的只是调色板上颜色的索引。

pf15bit和pf16bit:

这两种位图都是16位的,pf15bit是第一位为0,后15位的每5位分别表示红、绿、蓝。而pf16bit中绿色占6位,其它两种颜色占用5位(人眼对绿色比较敏感)!

pf24bit位图转pf15bit位图代码

var

Row24:pRGBTriple;

Row15:PWord;

forj:=0TOBitmap.Height-1DO

begin

Row15:=Bitmap15.Scanline[j];

Row24:=Bitmap24.Scanline[j];

fori:=0TOBitmap.Width-1DO

begin

withRow24^do

Row15^:=(rgbtRedShr3)Shl10or(rgbtGreenShr3)Shl5or(rgbtBlueShr3);

Inc(Row24);

Inc(Row15);

end

end;

pf24bit和pf32bit:

pf24bit上面的已多次用到,就不多说了。而pf32bit和pf24bit一样,用24位(前24位)来记录三原色的颜色信息!

PRGBQuad=^TRGBQuad;

tagRGBQUAD=packedrecord

rgbBlue:Byte;

rgbGreen:Byte;

rgbRed:Byte;

rgbReserved:Byte;

end;

TRGBQuad=tagRGBQUAD;

如果要修改上面的程序,就是简单的PRGBQuad替换PRGBTriple,TRGBQuad替换TRGBTriple的过程~

测试表明在pf32bit中利用Scanline处理图像要比pf24bit快。

所以除了单色图(PixelFormats=pf1bit)外(没必要),其它都可转外32位色实现灰度化。这也是一种比较可行的方法!

[优化篇]

还以上篇中给出的灰度化代码为例

procedureGrayscale(constBitmap:TBitmap);

var

X:Integer;

Y:Integer;

PRGB:pRGBTriple;

Gray:Byte;

begin

forY:=0to(Bitmap.Height-1)do

begin

PRGB:=Bitmap.ScanLine[Y];

forX:=0to(Bitmap.Wid

农村户口按照城市标准司法解释

th-1)do

begin

Gray:=Trunc(0.3*PRGB^.rgbtRed+0.59*PRGB^.rgbtGreen+0.11*PRGB^.rgbtBlue);

PRGB^.rgbtRed:=Gray;

PRGB^.rgbtGreen:=Gray;

PRGB^.rgbtBlue:=Gray;

Inc(PRGB);

end;

end;

end;

江阴春申路顺丰快递

际应用中,这种方法已经很快了,但实际上还存在可以优化的余地,什么呢?

Gray:=Trunc(0.3*Red+0.59*Green+0.11*Blue);//这句用的是浮点运算

在图像处理中,速度就是生命,能不用浮点运算,就最好不要用!

Gray:=(30*Red+59*Green+11*Blue)div100;

虽然这样一改,运算次数多了一次,但在我的雷鸟1.1G上,处理速度大概能提高5%左右!而同主频下(或略低,如Athlon1600+相当于P41.6G)AMD的CPU浮点运算能力比Intel的较强,整数运算能力较弱,所以用Intel的CPU在这里更能体现出优势!

注:xdiv100和Trunc(x/100)的效果是相同的,但查看其汇编代码可知一个用的指令是div,而另一个是fdiv(即进行浮点运算),还要调用函数Trunc,其处理速度差距非常大,所以能用xdiv100的时候就不要用Trunc(x/100)。

但这还不是最快的,再看一个:

Gray:=HiByte(77*Red+151*Green+28*Blue);

Gray:=(77*Red+151*Green+28*Blue)shr8;

(建议用后一种,不要调用函数)

这种方法比最原始的方法快了近3/4!

什么意思呢?用77,151,28分别除以256试试~~~

移位是什么意思呢,和10进制的进位,退位联系一下,是不是可以近似的理解为乘除2的n次方呢?当然这和真正意义的乘除法是不一样的!比如shr(右移),和真正的除法相比,比如shr1,只有最后一个字位为0时(既为2的倍数),它才等于除2!如二进制数110(6)右移1位变为11(3),和6/2=3结果相同。

当然这和一开始的灰度化效果有了些误差!

如果允许存在更大的误差,还可以考虑另一种方法:

Gray:=(Redshr2)+(Redshr4)+(Greenshr1)+(Greenshr4)+(Blueshr3);

连乘法都没用,完全用移位实现,结合上面的解释,用除法来理解该表达式,其值只是约等于(0.3125*Red+0.5625*Green+0.125*Blue),和一开始的加权平均值有了比较大的误差!但如果对速度有苛刻的要求的话,可以怎么用!这比上一种方法还能再快5%!

OK,关于bitmap or和bitmapor的内容到此结束了,希望对大家有所帮助。

相关内容