[转载]Android去掉标题栏、全屏的三种方法详解-Android新手入门-eoe Android开发者社区_Android开发论坛

mikel阅读(877)

[转载]Android去掉标题栏、全屏的三种方法详解-Android新手入门-eoe Android开发者社区_Android开发论坛.

第一种:也一般入门的时候经常使用的一种方法

requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏

注意这句一定要写在setContentView()方法的前面,不然会报错的第二种:在Android Manifest.xml文件中定义

代码片段,双击复制
01
<application Android:icon="@drawable/icon" android:label="@string/app_name"android:theme="@android:style/Theme.NoTitleBar">

可以看出,这样写的话,整个应用都会去掉标题栏,如果只想去掉某一个Activity的标题栏的话,可以把这个属性加到activity标签里面
第三种:这种在一般的应用中不常用,就是在res/values目录下面新建一个style.xml的文件例如

代码片段,双击复制
01
02
03
04
05
06
07
<?xml version="1.0" encoding="UTF-8" ?>
 
<resources>
<style name="notitle">
<item name="android:windowNoTitle">true</item>
</style>
</resources>

这样,我们就自定义了一个style,就相当于一个主题,然后在AndroidManifest.xml文件中定义

代码片段,双击复制
01
02
03
04
<application android:icon="@drawable/icon"
 
android:label="@string/app_name"
android:theme="@style/notitle">

这样也可以达到去掉标题栏的效果

三种去掉标题栏方法的总结

第一种,有的时候我们会看到,会先出现标题栏,然后再消失,因为我们只是在activity的oncreate方法中定义的,第二种相对第一种比较好一些,不会出现这种情况,第三种我个人感觉最好,这样把功能分开,便于维护和扩展

再介绍全屏的方法:第一种

代码片段,双击复制
01
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

第二种

代码片段,双击复制
01
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

第三种

代码片段,双击复制
01
application android:icon="@drawable/icon"

[转载]Android中一张图片加载后所占用内存大小的获取与测试 - juejiang - 博客园

mikel阅读(892)

[转载]Android中一张图片加载后所占用内存大小的获取与测试 – juejiang – 博客园.

Android程序中一旦加载的图片比较多,就有可能出现Out of Memory而导致程序崩溃。这个一方面是因为Android系统本身对于每个单独的进程有内存大小的限制(有16M,64M,128M,256M等 等),另一方面是因为Android系统对于图片资源的垃圾回收比较慢(文章http://jiangnane.com/index.php/archives/230中对Android源码进行了分析,发现Android的setImageViewBitmap(Bitmap bm)方法的源码中没有建立新的bitmap,而是用引用的方式来使用bm的,这就导致bm被多处引用)。

那一幅图片占用的内存大概多大呢?这篇博文主要是记录了我在测试一副图片占用字节数时查阅的一些资料和测试结果。

1.图片的表示方法

Android的Bitmap.Config给出了bitmap的一个像素所对应的存储方式,有RGB_565,ARGB_8888,ARGB_4444,ALPHA_8 四种。RGB_565表示的是红绿蓝三色分别用5,6,5个比特来存储,一个像素占用了5+6+5=16个比特。RGB_8888表示红绿蓝和半透明分别 用8,8,8,8个比特来存储,一个像素占用了8+8+8+8=32个比特。这样的话如果图片是以RGB_8888读入的,那么占用内存的大小将是 RGB_565读入方式的2倍。

  通常我们给Imagview加载图片是通过setDrawable或者在xml文件中用android:src来设置,从BitmapFactory.Options.inPreferredConfig的说明文档可以看出,默认的加载图片大小的方式是以RGB_8888读入的。

2.获取bitmap占用的字节数

API 12以上可以直接获取,以下则是通过获取高和行所占字节相乘得到的。

1
2
3
4
5
6
7
protected int sizeOf(Bitmap data) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
        return data.getRowBytes() * data.getHeight();
    } else {
        return data.getByteCount();
    }
}

来源:http://stackoverflow.com/a/2408164/1767800

3.以RGB_565方式读入图片

1
2
3
4
5
6
7
8
9
public  Bitmap readBitMap(Context context, int resId){ 
    BitmapFactory.Options opt = new BitmapFactory.Options(); 
    opt.inPreferredConfig = Bitmap.Config.RGB_565;  
   opt.inPurgeable = true
   opt.inInputShareable = true
      //获取资源图片 
   InputStream is = context.getResources().openRawResource(resId);
   return BitmapFactory.decodeStream(is,null,opt);
}

参考:http://blog.csdn.net/yangyangiud/article/details/12835885

4.获取ImageView和其中drawable的大小

获取ImageView和其中drawable大小需要在onWindowFocusChanged获取,在oncreate中返回的结果是0.

1
2
3
4
5
6
7
8
public void onWindowFocusChanged(boolean hasFocus){
        ImageView imageView=(ImageView)findViewById(R.id.test1);
        Log.v("Testresult","width= "+imageView.getWidth()+" height= "
        +imageView.getHeight());
        Log.v("Testresult","drawawidth= "+imageView.getDrawable().getBounds().width()+
                " drawableheight= "
        +imageView.getDrawable().getBounds().height());
    }

参考:http://stackoverflow.com/a/15128508/1767800

5.Oncreate()中的测试代码

复制代码
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ImageView imageView=(ImageView)findViewById(R.id.test1);
        Drawable drawable = imageView.getDrawable();
        int bitmapWidth = drawable.getIntrinsicWidth(); //this is the bitmap's width
        int bitmapHeight = drawable.getIntrinsicHeight(); //this is the bitmap's height
        Log.v("Testresult","bitmapwidth= "
                +bitmapWidth+" bitmapHeight= "+bitmapHeight);

        Bitmap bitmap=((BitmapDrawable)imageView.getDrawable()).getBitmap();
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
            Log.v("Testresult","bitmap bytes are"+bitmap.getRowBytes()*bitmap.getHeight());
        } else {
            Log.v("Testresult", "bitmap bytes are"+bitmap.getByteCount());
        }

        bitmap=readBitMap(this, R.drawable.pic_1000_562);
        //api 12之上可以直接获取bitmap所占用的字节数
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
            Log.v("Testresult","bitmap bytes are"+bitmap.getRowBytes()*bitmap.getHeight());
        } else {
            Log.v("Testresult", "bitmap bytes are"+bitmap.getByteCount());
        }

    }
复制代码

6.测试结果

其中原图片大小是1000*562,手机屏幕的分辨率是480*800.从图中可以看出,采用android:src的加载方式占用的字节数是采用 RGB_565加载方式的2倍。且1124000=2*1000*562字节。并且虽然在手机中显示的时候bitmap被缩小显示了,但是 drawable的长宽所占字节是和图片的尺寸相一致的。

[转载]Android开源介绍-UI组件 | Android 沉思录

mikel阅读(1180)

[转载]Android开源介绍-UI组件 | Android 沉思录.

终端的开发,UI的重要性不言而喻,如何快速开发出优雅漂亮的UI,Android的一些开源UI组件,提供了很好的参考。
参考:

 

oschina Android UI组件
最火的Android开源项目(一)
最火的Android开源项目(二)
最火的Android开源项目(完结篇)

 

1. ActionBarSherlock

 


在3.0之前使用ActionBar,ActionBarSherlock提供了很好的兼容。ActionBarSherlock 是Android compatibility library 的一个扩展,ActionBarSherlock 被设计成通过一个API就能够很方便使用所有版本的Android操作栏的设计模式.
对于Android 4.0及更高版本,ActionBarSherlock可以自动使用本地ActionBar实现,而对于之前没有ActionBar功能的版本,基于 Ice Cream Sandwich的自定义动作栏实现将自动围绕布局。能够让开发者轻松开发一款带动作栏(Action bar)的应用,并且适用于Android 2.x及其以上所有版本。
这个是Android牛人开发的一个开源组件,关注JakeWharton,你会有更多惊喜。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
import com.android.volley.toolbox.HurlStack;
import com.squareup.okhttp.OkHttpClient;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* An {@link com.android.volley.toolbox.HttpStack HttpStack} implementation which
* uses OkHttp as its transport.
*/
public class OkHttpStack extends HurlStack {
private final OkHttpClient client;
public OkHttpStack() {
this(new OkHttpClient());
}
public OkHttpStack(OkHttpClient client) {
if (client == null) {
throw new NullPointerException(“Client must not be null.”);
}
this.client = client;
}
@Override protected HttpURLConnection createConnection(URL url) throws IOException {
return client.open(url);
}
}
view raw OkHttpStack.java hosted with ❤ by GitHub

 

2. Android-ViewPagerIndicator

 

这个又是JakeWharton的杰作,说过了关注他,会有惊喜。
ViewPagerIndicator是扩展了support库中ViewPager的用法。
Paging indicator widgets compatible with the ViewPager from the Android Support Library and ActionBarSherlock. Originally based on Patrik Åkerfeldt’s ViewFlow

 

3. Android PullToRefresh

 

该项目为 Android 应用提供一个向下滑动即刷新列表的功能。这个很常用,现在的列表中,都提供了向下滑动刷新的功能。

 

4. Android瀑布流

 

实现了类似于迷尚android和蘑菇街android的瀑布流布局。
不过作者已经声明:

 

此项目由于最初设计问题,导致现在问题比较多,暂时停止维护。我现在在其他类似的瀑布流上进行完善开发,请关注:PinterestLikeAdapterView

看来作者还是很用心的,值得关注。

5. android-bootstrap

 


bootstrap,twitter开源的一个项目也叫这个。怎么看该项目都是一个聚合
android-bootstrap 是一个模板/引导/样板文件的应用程序,包括大量的优秀的开放源码工具和框架
Android Bootstrap 包含一个完整实现:Fragments, Fragment Pager, Account Manager, android-maven-plugin, Dagger, ActionBarSherlock 4, ViewPagerIndicator, http-request, GSON, Robotium for integration testing, API Consumption with an API on Parse.com and much more.
好东西啊,什么都有了,同学们自己挑选吧。

 

6. SlidingMenu

 

SlidingMenu是一个开源的Android库,能够让开发者轻松开发一款应用,实现类似于Google+、Youtube和Facebook应用中非常流行的滑动式菜单。
目前使用该项目的应用:

 

  • Foursquare
  • Rdio
  • Evernote Food
  • Plume
  • VLC for Android
  • ESPN ScoreCenter
  • MLS MatchDay
  • 9GAG
  • Wunderlist 2
  • The Verge
  • MTG Familiar
  • Mantano Reader
  • Falcon Pro (BETA)
  • MW3 Barracks

 

7. AndroidSideMenu

 

AndroidSideMenu能够让你轻而易举地创建侧滑菜单。需要注意的是,该项目自身并不提供任何创建菜单的工具,因此,开发者可以自由创建内部菜单。
这个与SlidingMenu结合,那岂不是天衣无缝了。

 

8. android-flip

 

能够实现Flipboard翻页效果的UI组件

 


是不是很酷啊

 

9. drag-sort-listview

 

DragSortListView(DSLV)是Android ListView的一个扩展,支持拖拽排序和左右滑动删除功能。重写了TouchInterceptor(TI)类来提供更加优美的拖拽动画效果。

 


DSLV主要特性:

 

-完美的拖拽支持;
-在拖动时提供更平滑的滚动列表滚动;
-支持每个ListItem高度的多样性
-公开startDrag()和stopDrag()方法;
-有公开的接口可以自定义拖动的View。
DragSortListView适用于带有任何优先级的列表:收藏夹、播放列表及清单等,算得上是目前Android开源实现拖动排序操作最完美的方案。

 

10. Android-satellite-menu

 

模拟path的按钮效果

 


对于Satellite Menu,其项目发起人siyamed表示,这种菜单结构就像是一个星球四周围绕着许多卫星,而这也就是他为何会以Satellite Menu命名该项目的原因。

 

11. ArcMenu

 

又见path的按钮效果

 

对于这个项目,其发起人daCapricorn表示,iOS版Path 2.0上的用户体验非常奇妙,但其Android版本却差太多。因此,他就尝试着在Android上做出像iOS版本那样的效果,而事实也的确如此。

 

12. ImageFilterForAndroid

 

在开源ImageFilterForAndroid中拥有许多丰富的图片效果,是由来自国内的代震军发起的一个开源项目。除了Android平台,还有Windows Phone和iOS移动平台,三个平台源码同步。
代震军也搞Android了吗,以前还看过他对Mongodb源码的分析。

 

13. Crouton

 

Crouton是Android上的一个可以让开发者对环境中的Toast进行替换的类,以一个应用程序窗口的方式显示,而其显示位置则由开发者自己决定。

 


以后自定义Toast,就很方便了。

 

14. Android-SlideExpandableListView

 

如果你对Android提供的Android ExpandableListView并不满意,一心想要实现诸如Spotify应用那般的效果,那么SlideExpandableListView绝对是你最好的选择。
该库允许你自定义每个列表项目中的ListView,一旦用户点击某个按钮,即可实现该列表项目区域滑动。

 

15. TimesSquare

 

Android下一款漂亮的日历控件

 

16. StandOut

 

StandOut 可让你轻松创建 Android 的浮动窗口

 

17. Notifications4EveryWhere

 

基于android 4.1 Notification 样式实现的兼容包。

 

改进自源com.android.support.v4.app 里面的NotificationCompat.Builder。

 

由于原官方的兼容包中,只是对Notification 做了一层api 的切换,并没有让旧的平台实现android 4.1 Notification 的新特性。所以,我对照着android4.1的源码把,android 4.1 的部分新的Notification 的特性进行移植,让android 2.2 以上的平台都能够用一致的api 实现同样的效果。

 

目前除了android 4.1 的bigStyle 还没实现外,其他我知道的特性都已经移植完毕。效果可以看主页的截图。

如果你之前有使用NotificationCompat.Builder 的,你只需把com.android.support.v4.app.NotificationCompat.Builder 替换成com.android.support.v8.app.NotificationCompat.Builder 即可。

[转载]Android--Activity的启动模式 - 承香墨影 - 博客园

mikel阅读(1042)

[转载]Android–Activity的启动模式 – 承香墨影 – 博客园.

前言

在一个Android应用中,不可避免的会包含多个Activity,当开启多个Activity之后,当按后退键时,一般会回退到上一个 Activity,这一点和浏览器有点类似,但是需要注意的是Android系统只能回退到上一个Activity,没办法前进到下一个 Activity,维护这个功能就需要了解到一个回退栈(Back Stack)的概念。

这篇博客就着重讲

  1. 什么是回退栈
  2. 回退栈的状态
  3. Activity的几种启动模式

 

什么是回退栈?

首先先来了解一下应用程序与进程的关系,众所周知,Android下有四大组件:Activity、Service、Receiver、 ContentProvider。一般开发一个应用程序,会包含多个Android组件,所以应用程序是一组组件的集合,而进程则是运行这些组件的载体。

而回退栈(Back Stack)只是针对Activity而言的,它是用来维护用的界面体验的,使一个Task让用户感觉就是一个应用,而无论其中的Activity是否来 自同一个应用程序,所以不要把回退栈和进程弄混了。设备的Home页面是大多数Task的起始位置,当用户点击一个应用程序图标的时候,应用的Task就 会来到前台,并把应用的主Activity压入BackStack的栈顶,并获得焦点,这个Activity称为根Activity,而在 BackStack中的Activity可以通过点击回退键弹出栈并销毁,这时就会使上一个Activity获得焦点,直到用户返回到Home页,而当 BackStack中的Activity都被弹出销毁之后,这个Task就不复存在了,但是这个程序的进程还存在(不在此时销毁)。

 

Task的状态

就像上面介绍的,每个Task都存在一个BackStack,而系统中可以存在多个Task,但是每次只有一个Task获得前台焦点,一般而 言,系统允许用户在多个Task中切换,而被至于后台的Task中的Activity,将被置于Stopped状态。实际上,同一个Task中的 Activity,只要不存在于栈顶并且获得前台焦点的Activity,那么它就是一个Stopped的状态。下图为官方文档中关于Task前后台的示 例图:

 

 

Activity的启动模式

根据Activity的不同的启动模式,它在BackStack中的状态是不一样的。Activity可以通过 AndroidManifest.xml清单文件配置,在<Activity />节点中的android:launchMode属性设置。它有四个选项:

 

standard

标准启动模式,也是默认启动模式,如果不设置android:launchMode属性的话。standard模式下的Activity会依照启动的顺序压入BackStack中。

下图是standard模式下,Activity的压栈和回退操作示意图:

singleTop

单顶模式,这种Activity启动模式,启动一个Activity的时候如果发现BackStack的栈顶已经存在这个Activity 了,就不会去重新创建新的Activity,而是复用这个栈顶已经存在的Activity,避免同一个Activity被重复开启。

下图是singleTop模式下,Activity的压栈和回退操作示意图:

singleTop的应用场景很多,一般适用于可以复用而又有多个开启渠道的Activity,避免当一个Activity已经开启并获得焦点 后,再次重复开启。比如说Android系统浏览器的书签页面,就是一个singleTop模式的Activity。Android的浏览器是基于 WebKit内核编写的,它是支持JavaScript脚本语言的,可以通过JavaScript脚本设置浏览器书签,这样如果存在多个页面存在保存书签 的JavaScript脚本,就会导致书签页面被多次开启,所以书签页面被设置为singleTop模式,这样可以避免在保存多个书签的时候重复开启书签 页面。

 

singleTask

开启一个Activity的时候,检查BackStack里面是否有这个Activity的实例存在,如果存在的话,情况BackStack里这个Activity上所有的其他Activity。

下图是singleTask模式下,Activity的压栈和回退操作示意图:

singleTask的的适用场景为一般程序的主页面,当回退到主页面的时候,清除BackStack中,它之上的所有Activity,这样 避免程序导航逻辑的混乱。比如Android系统的浏览器的主页面,就是singleTask模式的,上面提到,android下浏览器是Webkit内 核的,它是由C语言编写的,而每次打开新的网页如果重新开启一个Activity,是非常耗费系统资源的(需要解析HTML、Script脚本),所以被 设置为singleTask模式,这样在浏览器应用里,无论打开多少个页面,使用的都是同一个Activity。所以以后如果存在很耗费系统资源的 Activity,可以考虑使用singleTask开启模式。

 

singleInstance

被标记为singleInstance启动模式的Activity,在启动的时候,会开启一个新的BackStack,这个BackStack 里只有一个Activity的实例存在,并且把这个BackStack获得焦点。这是一种很极端的模式,它会导致整个设备的操作系统里,只会存在一个这个 Activity示例,无论是从何处被启动的。

下图是singleInstance模式下,Activity的压栈和回退操作示意图: 

singleInstance一般适用于需要在系统中只存在一个实例的场景,比如Android系统的来电页面,多次来电均使用的是一个Activity。

 

当然,在Android中,除了在AndroidManifest.xml清单文件中配置LauncherMode属性外,还可以在代码中设置 启动模式。在组件中,启动一个Activity,需要用到startActivity()方法,其中传递一个Intent,可以使用 Intent.setFlags(int flags)来设置新启动的Activity的启动模式,而通过代码设置Activity的启动模式的方式,优先级要高于在 AndroidManifest.xml清单文件中的配置。

Intent.setFlag(int flags)方法传递的一个整形的数据,被Android系统设置为了常量:

  • FLAG_ACTIVITY_NEW_TASK:这个标识会使新启动的Activity独立创建一个Task。
  • FLAG_ACTIVITY_CLEAR_TOP:这个标识会使新启动的Activity检查是否存在于Task中,如果存在则清除其之上的 Activity,使它获得焦点,并不重新实例化一个Activity,一般结合FLAG_ACTIVITY_NEW_TASK一起使用。
  • FLAG_ACTIVITY_SINGLE_TOP:等同于在LauncherMode属性设置为singleTop。

 

总结

这篇博客主要讲的是理论上的内容,也没什么示例代码,无非就是几种启动模式的特点需要注意一下,理解了Activity的启动模式,可以很好的提升用户的UI体验,对应用程序的推广是非常有好处的,毕竟一个用户体验很差的应用,是很难得到用户的推广的。

[转载]Kinect for Windows SDK开发入门(十九):Kinect Fusion - yangecnu - 博客园

mikel阅读(1073)

[转载]Kinect for Windows SDK开发入门(十九):Kinect Fusion – yangecnu – 博客园.

    Kinect for Windows SDK1.7中引入了Kinect Fusion功能。在1.8的SDK中对该功能进行了改进和强化,Kinect Fusion能够使得我们使用Kinect for Windows 传感器来进行真实场景的三维几何重建,目前已支持导出.obj及.stl等三维数据格式。Kinect Fusion技术在支持GPU加速的机器上能够对物体进行实时的三维建模。和传统的三维建模方式相比,Kinect Fusion最大的优势是快速便捷。

Kinect Fusion可以用于工业设计,3D打印,游戏制作,医疗教育等领域。

下图是Kinect Fusion的工作流程。Kinect传感器获取的深度影像数据在刚开始的时候有很多数据丢失,通过移动Kinect传感器对物体进行扫描,几秒钟过后就能够创建足够平滑的重建的静态场景,产生点阵云以及3D表面模型。

Figure 1

硬件要求

Kinect Fusion对计算机的硬件条件要求较高,Kinect Fusion能够使用C++ AMP技术在DirectX11兼容的GPU上处理数据,也可以在CPU上处理数据,可以在重建立方体构建的时候,通过设置重建的类型来确定。CPU处理 模式适合离线处理,只有最新的兼容DirectX 11的GPU才支持实时、交互性的重建。

基于GPU的重建的最低配置要求系统支持DirectX 11的显卡,如果达不到要求,Kinect Fusion就运行不起来。目前NVIDIA GeForce GTX560,AMD Radeon 6950,同类型或者比该类型显卡配置更高的硬件能够实现实时交互三维重建。

官方推荐配置是,台式机CPU主频3GH或以上,多核处理器,拥有2G内存的独立显卡。当然也可以使用配置有支持DirectX11 技术的显卡的笔记本, 但是运行速度比同类型的台式机会慢的多。通常支持每秒处理30帧图像就可以实现非常流畅的追踪和建模。

Kinect Fusion的工作原理

Kinect Fusion通过对从多个角度获取到的深度影像数据进行融合,来重建物体的单帧光滑表面模型。当传感器移动的时候,照相机的位置以及姿势信息被记录下来, 这些信息包括位置和朝向。由于我们知道了每一帧图像的姿势以及帧与帧之间的关联,多帧从不同角度采集的数据能够融合成单帧重建好的定点立方体。我们可以想 象下在空间中的一个巨大的虚拟立方体,里面是我们现实世界的场景,当我们移动传感器的时候,深度数据信息被不断加入。

下图是从Kinect Fusion的处理流程。

Figure 2 Kinect fusion Pipeline

  • 第 一步是深度影像数据的转换。SDK将Kinect中获取的原始深度帧数据转换为以米为单位的浮点数据,紧接着对该数据进行优化,通过获取摄像头的坐标信 息,将这些浮点数据转换为和Kinect摄像头朝向一致的点云数据。这些点的表面情况通过使用AlignPointClouds函数获取。
  • 第 二步是计算全局的摄像头的姿势信息,包括摄像头的位置和朝向,通过使用交互型的配准算法在摄像头移动时不断获取其姿势,这样系统始终知道当前摄像头相对于 起始帧时摄像头的相对姿势。Kinect Fusion中有两种配准算法。第一种叫NuiFusionAlignPointClouds,他用来将从重建对象计算得来的点云与从Kinect深度影 像数据中获取的点云进行配准。或者单独的使用比如对同一场景的不同视场角的数据进行配准;第二种叫 AlignDepthToReconstruction,该算法在对重建立方体进行处理时能够获得更高精度的追踪结果。但是对于场景内移动的物体该算法可 能不够健壮。如果场景中的追踪被中断,那么需要将摄像头的位置和上一次的摄像头位置对齐才能继续进行追踪。
  • 第三步是将从已知 姿势摄像头产生的深度影像数据融合为代表摄像头视野范围内的景物的立方体。这种对深度数据的融合是逐帧,连续进行的,同时通过平滑算法进行了去噪,也处理 了某些场景内的动态变化,比如场景内添加或者移除了小的物体等。随着传感器的移动从不同的视场角度观察物体表面。原始影像中没有表现出来的任何隔断或者空 也会被填充,随着摄像头更接近物体,通过使用新的更高精度的数据,物体表面会被持续优化
  • 最后,从传感器视点位置对重建立方体进行光线投射,重建的点阵云能够产生渲染了的三维重建立方体。

Kinect Fusion对物体的追踪仅仅使用Kinect 传感器产生的深度数据流。这种追踪主要依赖深度影像数据中不同位置深度数据有足够的深度差异。因此它能够将看到的数据融合起来以及计算传感器的不同位置差 异。如果将Kinect对准一个平整的墙面或者又很少起伏变化的物体,那么追踪可能不会成功。场景中物体分散时效果最好,所以在使用Kinect Fusion对场景进行追踪时如果出现追踪失败的情况,不防试着对场景内的物体进行追踪。

Kinect Fusion中的追踪有两种算法,他们分别通过AlignDepthFloatToReconstruction和 AlignPointClouds 函数实现,他们都可以用于摄像头位置的追踪,但是,如果我们使用AlignDepthFloatToReconstruction 函数来创建一个重建立方体,可能会有更好的追踪精度。相比,AlignPointClouds 方法可以用于单独的,不需要重建立方体就可以将两个点云进行对齐。

相关API

前面讲解了Kinect Fusion的工作原理,通过SDK中的相关API,我们可以使用Kinect Fusion来对真是场景进行三维重建,下图是Kinect Fusion相关的处理流程:

KF modeling pipeline

首先,需要进行初始化,在初始化阶段,Kinect Fusion会确定建模过程中的世界坐标系,并会构造一个带扫描的真实场景的静态的虚拟的立方体,在建模过程中,我们只关心在该虚拟立方体中的真实场景。

紧接着第一步是对每一帧深度影像数据进行如上图所示的处理。下面就简单介绍下上图中涉及Kinect Fusion的相关函数。

DepthToDepthFloatFrame 函数

该函数的签名如下:

public void DepthToDepthFloatFrame(DepthImagePixel[] depthImageData, FusionFloatImageFrame depthFloatFrame,float minDepthClip, float maxDepthClip, bool mirrorDepth)

该方法将无符号短型深度影像数据帧格式转换为浮点型深度影像数据桢格式,它代表物体距离Kinect传感器的距离,处理好的数据存储在预分配的 depthFloatFrame中,参数中depthImageData 和 depthFloatFrame 的大小必须一致,该函数在GPU上运行。

depthImageData 是从Kinect传感器获取的深度影像原始数据。minDepthClip 表示最小深度阈值,小于该值得都会设置为0,maxDepthClip 为最大深度阈值,大于该值得都被设置为1000,最后一个布尔型的mirrorDepth表示是否对深度数据进行镜像处理。

最小最大深度阈值可以用来对输入的数据进行处理,比如说可以排除某些特殊的物体,将这些物体排除在三维重建之外。

ProcessFrame 函数

接下来可以调用ProcessFrame函数,该函数在内部其实是先后调用了AlignDepthFloatToReconstruction 和 IntegrateFrame 这两个函数,这里先介绍ProcessFrame函数。

public bool ProcessFrame(FusionFloatImageFrame depthFloatFrame, int maxAlignIterationCount, int maxIntegrationWeight,Matrix4 worldToCameraTransform)

该函数用来对每一帧经过DepthToDepthFloatFrame处理后的深度影像数据进行进一步处理。如果在 AlignDepthFloatToReconstruction阶段追踪产生错误,那么接下来的IntegrateFrame阶段就不会进行处理,相机 的姿势也保持不变。该函数支持的最大图像分辨率为640*480。

maxAlignIterationCount参数为配准过程中的迭代次数,该参数用来表示对齐相机追踪算法的迭代次数,最小值为1,值越小的计算速度更快,但是设置过小会导致配准过程不收敛,从而得不到正确的转换。

maxIntegrationWeight 参数用来控制深度影像融合的平滑参数,值过小会使得的图像具有更多的噪点,但是物体的移动显示的更快,消失的也更快,因此比较适合动态场景建模。大的值使得物体融合的更慢,但是会保有更多的细节,噪点更少。

WorldToCameralTransoform,参数为最新的相机位置。

如果该方法返回true,则表示处理成功,如果返回false,则表示算法在对深度影像数据对齐的时候遇到问题,不能够计算出正确的变换。

我们一般的可以分别调用AlignDepthFloatToReconstruction 和 IntegrateFrame 这两个函数,从而可以对更多的细节进行控制,但是,ProcessFrame速度可能更快,该方法处理成功之后,如果需要输出重构图像,则只需要调用 CalculatePointCloud方法,然后调用FusionDepthProcessor.ShadePointCloud即可。

AlignDepthFloatToReconstruction 函数

public bool AlignDepthFloatToReconstruction(FusionFloatImageFrame depthFloatFrame,int maxAlignIterationCount,FusionFloatImageFrame deltaFromReferenceFrame, out float alignmentEnergy, Matrix4 worldToCameraTransform)

该方法用来将深度影像数据桢匹配到重构立方体空间,并由此计算出当前深度数据帧的摄像头的空间相对位置。相机追踪算法需要重构立方体,如果追踪成功,会更新相机的内部位置。该方法支持的最大分辨率为 640*480。

maxAlignIterationCount 参数和ProcessFrame方法中的参数含义相同。

deltaFromReferenceFrame 表示配准误差数据桢, 是一个预先分配的浮点影像帧,通常存储每一个观测到的像素与之前的参考影像帧的对齐程度。通常可以用来产生彩色渲染或者用来作为其他视觉处理算法的参数, 比如对象分割算法的参数。这些残差值被归一化到-1 ~1 的范围内,代表每一个像素的配准误差程度。如果合法的深度值存在,但是没有重构立方体,那么该值就为0 表示完美的对齐到重构立方体上了。如果深度值不合法,就为返回1。如果不需要这个返回信息,直接传入null即可。

alignmentEnergy 表示配准精确程度 ,0表示完美匹配

worldToCameraTransform 表示此刻计算得到的相机位置,通常该变量通过调用FusionDepthProcessor.AlignPointClouds 或者 AlignDepthFloatToReconstruction这两个方法获得。

该函数如果返回true则表示对齐成功,返回false表示则表示算法在对深度影像数据对齐的时候遇到问题,不能够计算出正确的变换。

IntegrateFrame 函数

public void IntegrateFrame(FusionFloatImageFrame depthFloatFrame,int maxIntegrationWeight, Matrix4 worldToCameraTransform)

用于融合深度数据桢到重构场景中maxIntegrationWeight,控制融合的平滑程度 。

worldToCameraTransform 表示此时深度数据帧的相机位置,他可以由配准API计算返回。

CalculatePointCloud 函数

public void CalculatePointCloud(FusionPointCloudImageFrame pointCloudFrame,Matrix4 worldToCameraTransform)

通过光线跟踪算法计算出某视点下的点云数据。

这些点云信息可以被用作 FusionDepthProcessor.AlignPointClouds或者FusionDepthProcessor.ShadePointCloud函数的参数。从而来产生可视化的图像输出。

pointCloudFrame参数是一个固定的图像大小,比如说,你可以窗体大小范围内的点云数据,然后放置一个image控件,通过调用 FusionDepthProcessor.ShadePointCloud来填充这个image控件,但是需要注意的是,图像越大,计算所耗费的资源就 越多。

pointCloudFrame 参数是一个预先分配的点云数据桢,他会被通过对重建立方体进行光线投射得到的点云数据进行填充,通常通过调用 FusionDepthProcessor.AlignPointClouds 或者FusionDepthProcessor.ShadePointCloud.函数产生。

worldToCameraTransform参数表示相机视点的位置,用来表示光线投射的位置。

CalculateMesh 函数

public Mesh CalculateMesh(int voxelStep)

用于返回重构场景的几何网络模型。该函数从重建立方体输出一个多边形立体表面模型。voxelStep 描述了采样步长,采样步长设置的越小,返回的模型就越精致。

四 结语

理解了这几个函数,那么就应该差不多能够使用Kinect Fusion提供的功能了,最好的学习方式就是直接查看Kinect Developer Toolkit中提供的示例程序的代码,相信理解了上面的函数,看起来应该不会太吃力。

由于本人笔记本配置达不到要求,所以没有办法演示,不过相信通过上面的介绍,对您了解和使用Kinect Fusion应该会有所帮助。

[转载]Android ListView添加多种类型的ItemView - sw926 - 博客园

mikel阅读(1042)

[转载]Android ListView添加多种类型的ItemView – sw926 – 博客园.

一般复杂的ListView都会重写BaseAdapter,通过重用convertView来减少inflate,通过setTag()和ViewHolder改变ItemView的内容。

重写BaseAdapter必须要实现

public int getCount()

public Object getItem(int position)

public View getView(int position, View convertView, ViewGroup parent)

这三个函数。

补充一下ListView的ViewHolder机制:

Android中inflate是比较耗费资源的,如果每次getView都执行inflate,那么很容易造成内存溢出,所以要在 getView中重用convertView,如果convertView已经进行了inflate,那么只要对view进行赋值就可以,比如 setText()。所以当convertView为空时才会执行inflate,当convertView不为空时,只执行赋值操作。通过给 convertView设置一个tag来记录view的引用,还可以减少findViewById()的次数。

在默认情况下,Adapter只保存一个convertView,可以简单的认为,每次getView()时的convertView都是上次 getView时return的view。这种情况显然是不能实现多种类型的ItemView的,如何才能在getView时让convertView是 我们想要的布局类型呢,BaseAdapter还有两个可以重写的函数:

public int getItemViewType(int position)

public int getViewTypeCount()

看到这两个函数应该很多人都明白了,getViewTypeCount()就是获取列表有几种布局类型,getItemViewType(int position)是获取在position位置上的布局类型。

通过一个小Demo来测试一下,写一个有3中布局的列表,3中布局分别是TextView,EditText,Button,

首先实现列表的ListItem

复制代码
package com.example.testmultipletypelist;

public class ListItem {

    public static final int TYPE_TEXT = 0;
    public static final int TYPE_EDIT = 1;
    public static final int TYPE_BUTTON = 2;
    public static final int TYPE_COUNT = 3;

    private String name;
    private int type;

    public ListItem(int type, String name) {
        this.type = type;
        this.name = name;
    }

    public int getType() {
        return type;
    }

    public String getName() {
        return name;
    }
}
复制代码

重写BaseAdapter中的getItemViewType()和getViewTypeCount()。

复制代码
    @Override
    public int getItemViewType(int position) {
        if (list != null && position < list.size()) {
            return list.get(position).getType();
        }
        return super.getItemViewType(position);
    }

    @Override
    public int getViewTypeCount() {
        return ListItem.TYPE_COUNT;
    }
复制代码

然后在getView()中,可以通过getItemViewType()来处理不同的布局

复制代码
@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        int type = getItemViewType(position);
        switch (type) {
        case ListItem.TYPE_TEXT: {
            TextViewHolder holder = null;
            if (convertView == null) {
                convertView = activity.getLayoutInflater().inflate(R.layout.list_test_item, null);
                holder = new TextViewHolder();
                holder.textView = (TextView) convertView.findViewById(R.id.tv_text);
                convertView.setTag(holder);
            } else {
                holder = (TextViewHolder) convertView.getTag();
            }
            holder.textView.setText(list.get(position).getName());
            break;
        }
        case ListItem.TYPE_EDIT: {
            EditViewHolder holder = null;
            if (convertView == null) {
                convertView = activity.getLayoutInflater().inflate(R.layout.list_edittext_item, null);
                holder = new EditViewHolder();
                holder.editText = (EditText) convertView.findViewById(R.id.ed_edittext);
                convertView.setTag(holder);
            } else {
                holder = (EditViewHolder) convertView.getTag();
            }
            holder.editText.setText(list.get(position).getName());
            break;
        }
        case ListItem.TYPE_BUTTON: {
            ButtonViewHolder holder = null;
            if (convertView == null) {
                convertView = activity.getLayoutInflater().inflate(R.layout.list_button_item, null);
                holder = new ButtonViewHolder();
                holder.button = (Button) convertView.findViewById(R.id.btn_button);
                convertView.setTag(holder);
            } else {
                holder = (ButtonViewHolder) convertView.getTag();
            }
            holder.button.setText(list.get(position).getName());
            break;
        }
        default:
            break;
        }

        return convertView;
    }
复制代码

运行效果

Demo下载

[转载]构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(4)-构建项目解决方案 创建EF Model Frist模式 - ymnets - 博客园

mikel阅读(1068)

[转载]构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(4)-构建项目解决方案 创建EF Model Frist模式 – ymnets – 博客园.

进行本次文章之前,我们可能需要补充一些基本知识。

首先我们系统是基于接口编程的,我们为什么要使用借口编程,其实这是应用了一种企业应用架构模式

Repository(仓储)

  一种用来封装存储,读取和查找行为的机制,它模拟了一个对象集合。

支持在领域和数据映射层之间实现彻底分离和单向依赖关系的目标。

接口编程

最主要的目的是使关注点分离,让开发人员各司其职

  代码封存保密,分包开发,无需要给予逻辑结构代码,只需要给予接口文件

  缺点:设计困难,比传统的三层,单类模式困难,但是接口程序员工资都很高!

AOP(面向方面编程)

  我们为了弥补面向对象缺陷,我们系统将引入面向方面编程

  主要用于日志记录,事务处理,异常处理等等。

概念这种东西过于模糊,我们必须经历过一个大系统才能认识这些概念模型。我无法用文章来下详细解析此系统的深层概念,需要大家在日常工作中实践和意会,推荐一本.net的设计书籍《Microsoft .NET企业级应用架构设计》这本书详细的讲述了接口编程,面向方面编程

通过上面我们需要构建项目的解决方案。

虽然MVC的controller层包含了逻辑,但是对于一个大系统,我们不可能把业务和数据库底层包含在一起,虽然提供了Models模型文件 夹,在第二讲我把他删除了,我们将这一层Model层提取出来,任何层的设计都好,都是从三层设计模式衍生出来的,本系统也不例外。我们是基于接口编程的 仓储模式,所以我们必须有BLL,IBLL,DAL,IDAL的对应类库。

好,现在我们右键我们的解决方案吧。分别建立

  • App.BLL (业务层)
  • App.IBLL (业务层接口)
  • App.DAL (数据层)
  • App.IDAL (数据层接口)
  • App.Models (模型)
  • App.Common(通用类库)
  • App.Core (核心类库)

图:

添加:EF5.0 VS2012旗舰版默认已经集成安装了EF5.0我们把他存放到App.Models类库下

右键—-添加新建项

输入名称DB大家自己取名称,这里选择空模型,我们是模型优先模式,不是code frist模式要注意。对于系统来说我认为模型优先是有优势的

展开DB.edmx删除DB.Context.tt和DB.tt才能正确使用Model Frist模式,看到DB.edmx的属性窗口,将代码生成策略一项的无改为默认值

我们打开SQL Server如果你安装了VS2012我相信你的数据库也不老,我是SQL Server2008 R2版本

我们建立一个简单的事例表吧:

Create database DB 创建一个名称为DB的数据库

复制代码
use DB

CREATE TABLE [dbo].[SysSample](
[Id] [varchar](50) NOT NULL,
[Name] [varchar](50) NULL,
[Age] [int] NULL,
[Bir] [datetime] NULL,
[Photo] [varchar](50) NULL,
[Note] [text] NULL,
[CreateTime] [datetime] NULL,
CONSTRAINT [PK__SysSampl__3214EC075AEE82B9] PRIMARY KEY CLUSTERED
复制代码

好了有了数据库和表,我们往数据库添加模型映射,说到这里我简单说说我们用EF的原理,EF是一个ORM框架,ORM是通过描述对象和关系数据库之 间的映射,将程序中的对象自动持久化到关系数据库中,简单易用、性能突出的泛型持久化支持,则将使您能够将更多注意力集中到业务开发,所以大家懂要懂得什 么是事务,加入我们从数据库取出10条数据,我删除了1条,过一会在删除1条,只要我提交事务才到数据库执行删除,否则将是删除内存的数据库,所以数据库 的压力小了,内存的压力大了。

新建连接—–选择Microsoft SQL server


相信你此时已经看到了效果了,我可能写得太详细了,文章有点乱。

如果你用过熟悉三层架构,那现在可以动手对项目之间的关系进行引用了。

下面给出一个引用流程:按照这个来进行引用,有了更清楚的让大家看出注入,我们目前这样引用

App.Admin————-App.Models,App.Common,App.Core,App.IBLL,App.BLL,App.DAL,App.IDAL,System.Data.Entity

App.BLL———–App.Models,App.IBLL,App.DAL,App.IDAL,System.Data.Entity

App.BLL————–App.IBLL,System.Data.Entity

App.DAL————–App.IDAL,System.Data.Entity

App.IDAL————–System.Data.Entity

下一讲我们将利用接口编程我们实现一个增删改代码,一些糟糕的代码

[转载]VMWare中安装Mac OS Lion和XCode的注意事项 - 余璜的技术博客 - 博客频道 - CSDN.NET

mikel阅读(888)

[转载]VMWare中安装Mac OS Lion和XCode的注意事项 – 余璜的技术博客 – 博客频道 – CSDN.NET.

1. MacOS安装

 

a) 请使用VMWare 7.1.x,我用的是7.1.4,注册码是网上找的。

 

b) 为了顺利安装VMWare补丁,一定要将VMWare装在C盘默认位置。一般为 C:\program files\VMWare\VMWare Workstation

 

c) 在安装MacOS前,必须对VMWare进行打补丁,目的是让Windows的平台下的VMWare能够运行MacOS。否则:在出现MacOS启动屏幕 数秒后虚拟机运行窗口会自动关闭,并在右下角提示“The guest operating system is not Mac OS X Server.”

 

 

 

2. VMWare Tools的安装

 

a) 为了性能考虑,必须安装VMWare Tools。该软件在darwin.iso中。请使用VMWare提供的挂在工具,将其作为CDROM挂在到Mac中,进入并安装。

 

b) Mac中的用户名为MagicStudio,安装密码为sssssssss   (9个s)

 

 

 

3. 显示补丁

 

a) 为了解决花屏问题,必须安装显示补丁。安装方法,下载补丁,然后将其放入到VMWare的共享文件夹中,然后在Mac中打开并安装。注意:共享文件夹路径中不能出现中文!!!

 

 

 

4. 让你的XCode支持iOS 5.0以上的硬件调试,请下载XCode 4.3版

 

a) 最开始的时候我下载了XCode 4.1,刚才才发现,十分傻逼。傻逼有2:其一,XCOde 4.1超级大,4GB多, 其二,XCode 4.1 preview版本,只支持iOS 4.3及以下版本,如果你想测试iOS 5.0以上的硬件,没戏。XCode 4.2大小才1GB多点,支持iOS 5.0以上版本。

 

b) 如果你安装的Mac是Mac Lion 10.7版本,请安装XCode 4.2,不要下载XCode 4.3,因为后者要求系统版本必须为10.7.x以上,可能会给你带来麻烦。

 

 

 

对于最新买到的ipad,iOS版本基本都是5.0以上。千万注意。XCode 4.3官方地址:https://developer.apple.com/downloads/index.action#

 

 

 

5. 虚拟机里面测试硬件,报告找不到provision

 

a) 请先切换到VMWare中的iOS,然后再插入ipad到USB,这样XCode才能探测到ipad的插入,才能将app直接丢到pad上执行。另外,可能需要在iTunes里面对pad授权一下?不确定这一步,反正我做了。

 

 

 

 

 

OK~

 

 

 

 

 

附录(列出各个文件的关键字,便于搜索下载):

 

1. VMWare补丁: macosx_guest_vmware_7.tar.gz

 

2. Mac显示器花屏补丁:VMDrivers_Mac.rar

 

3. Mac Lion版本: Mac.OSX.10.7(纯净OS)-VM.rar

 

4. VMWare虚拟机:VMware-workstation-full-7.1.4

 

5. XCode 4.2

 


 

我用了2核,2G内存跑虚拟机,不卡。编译一个XCode的iOS默认demo,很快。

 


 

参考文献:http://www.chinamac.com/download/mac8191.html

 

 

 

一个很不错的iOS编程开发教程:

 

IOS/xcode4.0以上最新开发视频教程+实战项目视频+源代码

 

相比于自己去辛辛苦苦网上搜集乱七八糟的资料,这里效率要高太多!

 

 

 

 

 

 

 

 

 

 

 

iOS开发资源:

 

各种图书:http://bbs.weiphone.com/read-htm-tid-2323882.html

 

 

 


iOS 5 开发的好东西【本地下载】 http://bbs.weiphone.com/read-htm-tid-4008975.html


下载要顶及加分呀
很多帖子都有 iOS 4 开发的好东西
但只有这里是【本地下载】及有【源代码】

 


 


基础类 Beginning iPhone 4 Development Exploring the iOS SDK


 



pdf + 源代码:  Beginning iPhone 4 Development Exploring the iOS SDK+code.rar (12021 K) 下载次数:7052 

pdf:  Beginning iPhone 4 Development Exploring the iOS SDK.pdf (11666 K) 下载次数:3105 



 


基础类 iOS SDK Programming : A Beginner’s Guide


 



rar 压缩:  iOS SDK Programming A Beginners Guide.pdf.rar (12061 K) 下载次数:1155 

pdf 版本:  iOS SDK Programming A Beginners Guide.pdf (14411 K) 下载次数:1625 

源代码 :  iOS SDK Sample Code.zip (13446 K) 下载次数:1604 




 


基础类 Programming iOS 4: Fundamentals of iPhone, iPad, and iPod touch Development


 



pdf + 源代码:  Programming iOS 4+code.rar (12203 K) 下载次数:1185 

源代码 :  Programming-iOS-4-Book-Examples-09d82b5.zip (3343 K) 下载次数:1291 

 


 


基础类 From Idea to App: Creating iOS UI, animations, and gestures


 



pdf + 源代码:  From Idea to App+code.rar (8053 K) 下载次数:3139 

pdf 版本:  From Idea to App.pdf (5131 K) 下载次数:622 

源代码 :  From Idea to App_code.rar (5275 K) 下载次数:650 




 


ObjC 基础类 Programming in Objective-C, 3rd Edition


 



pdf 版本:   Programming in Objective-C 3rd Edition.pdf (4505 K) 下载次数:3966 

源代码: http : // classroom m.com/objective-c/index.php?board=56.0




 


基础类 iOS Programming: The Big Nerd Ranch Guide, 2nd Edition


 



pdf 版本:   iOS Programming 2nd Edition.pdf (14432 K) 下载次数:1121 

源代码 :   iOSProgramming.zip (6881 K) 下载次数:1406 




 


实用类 iOS 4 Programming CookBook


 



pdf + 源代码:  iOS4ProgrammingCookBook+code.rar (11197 K) 下载次数:2033 

pdf 版本:  iOS4ProgrammingCookBook.pdf (7918 K) 下载次数:1031 

源代码 :  iOS4ProgrammingCookBook_code.rar (5763 K) 下载次数:965 




 


实用类 Tips and Tricks for Awesome iPhone and iPad Apps


 



pdf + 源代码 :  iOS Recipes Tips and Tricks for Awesome iPhone and iPad Apps.pdf+code.rar (11068 K) 下载次数:1426 

pdf 版本:  iOS Recipes Tips and Tricks for Awesome iPhone and iPad Apps.pdf (1290 K) 下载次数:440 

源代码 :  cdirec-code.zip (10513 K) 下载次数:802 




 


专题类 Advanced iOS 4 Programming


 



pdf 版本:  Advanced iOS 4 Programming.pdf (3431 K) 下载次数:1434 

源代码 :  Advanced iOS 4 Programming_code.rar (15769 K) 下载次数:1033 




 


专题类 Concurrent Programming in Mac OS X and iOS


 



1. Introducing Block Objects
2. Programming Grand Central Dispatch 
pdf + 源代码:  Concurrent Programming in Mac OS X and iOS+code.rar (3326 K) 下载次数:1362 

pdf 版本:   Concurrent Programming in Mac OS X and iOS.pdf (3975 K) 下载次数:429 

源代码 :  Concurrent Programming_code.zip (536 K) 下载次数:400 




 


专题类 Core Data iOS Essentials


 



rar 压缩:  Core Data iOS Essentials.pdf.rar (8616 K) 下载次数:1820 

pdf 版本:  Core Data iOS Essentials.pdf (11224 K) 下载次数:1190 

源代码 :  Core Data iOS Essentials_Code.zip (11325 K) 下载次数:1941 



 


专题类 Pro Core Data for iOS


 



pdf + 源代码:  Pro Core Data for iOS+code.rar (12890 K) 下载次数:2413 

pdf 版本:  Pro Core Data for iOS.pdf (7085 K) 下载次数:658 

源代码 :  Pro Core Data for iOS_code.zip (6751 K) 下载次数:563 




 


专题类 Graphics and Animation on iOS


 



rar 压缩:  Graphics and Animation on iOS.pdf.rar (3738 K) 下载次数:1539 

pdf 版本:  Graphics and Animation on iOS.pdf (5267 K) 下载次数:632 

源代码 :  Chapter_01.zip (2055 K) 下载次数:2781 




 


专题类 Pro Objective-C Design Patterns for iOS


 



pdf + 源代码:  Pro Objective-C Design Patterns for iOS+code.rar (4573 K) 下载次数:1555 

pdf 版本:  Pro Objective-C Design Patterns for iOS.pdf (3563 K) 下载次数:563 

源代码 :  Pro Objective-C Design Patterns for iOS_code.zip (1557 K) 下载次数:882 



 


游戏类 Learning Cocos2D


 




pdf 版本:   Learning Cocos2D.pdf (14667 K) 下载次数:1702 

源代码 : http://cocos2dbook.com/projects/LearningCocos2D_Resources_SourceCode_v1_1.dmg



Learn iPhone and iPad Cocos2D Game Development, Cocos2d for iPhone 0.99 Beginners Guide 书及源代码


 


【官方下载链接】


 




Xcode 4.1 and iOS SDK 4.3.x for Lion (要求 10.7)【官方下载链接, 下载需要开发者帐号】

Xcode 4.0.2 and iOS SDK 4.3.2 for Snow Leopard (要求 10.6.6)【官方下载链接, 下载需要开发者帐号】

Xcode 3.2.6 and iOS SDK 4.3.1 for Snow Leopard (要求 10.6.6)【官方下载链接, 下载需要开发者帐号】
Xcode 3.2.6 and iOS SDK 4.3.1 for Snow Leopard (要求 10.6.6)【官方下载链接, 下载需要开发者帐号】

Xcode 3.2.5 and iOS SDK 4.2 for Snow Leopard (要求 10.6.4)【官方下载链接, 下载需要开发者帐号】
Xcode 3.2.4 and iOS SDK 4.1 for Snow Leopard (要求 10.6.4)【官方下载链接, 下载需要开发者帐号】
Xcode 3.2.3 and iPhone SDK 4 Final for Snow Leopard (要求 10.6.2)【官方下载链接, 下载需要开发者帐号】



The Objective-C Programming Language (pdf)【官方 pdf 链接】
Object-Oriented Programming with Objective-C (pdf)【官方 pdf 链接】
Cocoa Fundamentals Guide (pdf)【官方 pdf 链接】
iOS Application Programming Guide (pdf)【官方 pdf 链接】
View Programming Guide for iOS (pdf)【官方 pdf 链接】
View Controller Programming Guide for iOS (pdf)【官方 pdf 链接】
Table View Programming Guide for iOS (pdf)【官方 pdf 链接】
Scroll View Programming Guide for iOS (pdf)【官方 pdf 链接】
Collections Programming Topics (pdf)【官方 pdf 链接】
Text, Web, and Editing Programming Guide for iOS (pdf)【官方 pdf 链接】
Camera Programming Topics for iOS (pdf)【官方 pdf 链接】
Address Book Programming Guide for iOS (pdf)【官方 pdf 链接】
Event Kit Programming Guide (pdf)【官方 pdf 链接】
Local and Push Notification Programming Guide (pdf)【官方 pdf 链接】
System Messaging Programming Topics for iOS (pdf)【官方 pdf 链接】
Core Data Programming Guide (pdf)【官方 pdf 链接】
Core Animation Programming Guide (pdf)【官方 pdf 链接】
Quartz 2D Programming Guide (pdf)【官方 pdf 链接】
OpenGL ES Programming Guide for iOS (pdf)【官方 pdf 链接】

iOS Debugging Magic http://developer.apple.com/library/ios/#technotes/tn2239/_index.html
pdf   iOS Debugging Magic.pdf (388 K) 下载次数:455 


iOS 3 的好东西
iPhone SDK 3.1.3 with XCode 3.1.4 for Leopard (要求 10.5.7) 【官方下载链接】
iPhone SDK 3.1.3 with XCode 3.2.1 for Snow Leopard (要求 10.6.0) 【官方下载链接】
iPhone SDK 3.2 Final with Xcode 3.2.2 for Snow Leopard (要求 10.6.0)【官方下载链接】

[中文扫描版]Objective-C.2.0 程序设计(原书第2版) + iPhone 3开发基础教程
Learn iPhone and iPad Cocos2D Game Development, Cocos2d for iPhone 0.99 Beginners Guide 书及源代码
7本开发 iPhone OpenGL 游戏好东西
20多本+4视频 开发iPhone好东西【本地下载】

[转载]Android--操作图片Exif信息 - 承香墨影 - 博客园

mikel阅读(1001)

[转载]Android–操作图片Exif信息 – 承香墨影 – 博客园.

前言

之前将Android如何加载大分辨率的时候有讲到,图片文件在内存中以像素点的二维数组加载,存放像素信息,还会在开头加上一些额外的照片拍 摄参数信息,这些信息就是Exif。Android2.0之后,媒体库加入了操作图片Exif的类,本篇博客主要讲解如何在Android应用中操作图片 的Exif信息。

本篇博客主要内容:

  1. 什么是Exif
  2. ExifInterface
  3. 操作Exif

 

什么是Exif

先来了解什么是Exif。Exif是一种图像文件格式,它的数据存储于JPEG格式是完全相同的,实际上Exif格式就是JPEG格式头插入 了数码照片的信息,包括拍摄的光圈、快门、平衡白、ISO、焦距、日期时间等各种和拍摄条件以及相机品牌、型号、色彩编码以及GPS等。简单来 说,Exif=拍摄参数+JPED。因此,可以利用任何可以查看JPEG文件的看图软件浏览Exif信息,但是并不是所有图形程序都能处理Exif信息, 而自Android2.0之后,加入了对图片Exif数据的支持。

ExifInterface

在Android下,通过ExifInterface类操作图片的Exif信息,虽然这个类的名字包含Interface,但它不是一个接 口,它是一个类,处于android.media.ExifInterface包下,是媒体库的一部分功能的实现。ExifInterface有一个构造 函数,接受一个String类型的数据,此为读取图片文件的地址。

Exif数据在图片中可以理解为Key-value键值对的方式存储,一般通过如下几个方法操作:

  • String getAttribute(String tag):获取图片中属性为tag的字符串值。
  • double getAttribute(String tag,double defaultValue):获取图片中属性为tag的double值。
  • int getAttributeInt(String tag,defaultValue):获取图片中属性为tag的int值。
  • void setAttribute(String tag,String value):根据输入参数,设定图片Exif的值。
  • void saveAttrubutes():把内存中图片的Exif写入到图片中。

可以看到,上面大部分方法操作了一个String类型的tag参数,此为Exif的属性,在ExifInterface中定义了一些字符串的静态常量表示这些tag值,常用如下:

  • TAG_APERTURE:光圈值。
  • TAG_DATETIME:拍摄时间,取决于设备设置的时间。
  • TAG_EXPOSURE_TIME:曝光时间。
  • TAG_FLASH:闪光灯。
  • TAG_FOCAL_LENGTH:焦距。
  • TAG_IMAGE_LENGTH:图片高度。
  • TAG_IMAGE_WIDTH:图片宽度。
  • TAG_ISO:ISO。
  • TAG_MAKE:设备品牌。
  • TAG_MODEL:设备型号,整形表示,在ExifInterface中有常量对应表示。
  • TAG_ORIENTATION:旋转角度,整形表示,在ExifInterface中有常量对应表示。

以上常量不包括GPS的信息,实际上Exif还可以保存拍摄时GPS的信息,但是需要设备支持。下面通过一个Demo,讲解一下这些参数的获取与值的展示:

代码如下:

btn_readExifInLog.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
try {
ExifInterface exifInterface = new ExifInterface(
"/sdcard/a.jpg");
String FFNumber = exifInterface
.getAttribute(ExifInterface.TAG_APERTURE);
String FDateTime = exifInterface
.getAttribute(ExifInterface.TAG_DATETIME);
String FExposureTime = exifInterface
.getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
String FFlash = exifInterface
.getAttribute(ExifInterface.TAG_FLASH);
String FFocalLength = exifInterface
.getAttribute(ExifInterface.TAG_FOCAL_LENGTH);
String FImageLength = exifInterface
.getAttribute(ExifInterface.TAG_IMAGE_LENGTH);
String FImageWidth = exifInterface
.getAttribute(ExifInterface.TAG_IMAGE_WIDTH);
String FISOSpeedRatings = exifInterface
.getAttribute(ExifInterface.TAG_ISO);
String FMake = exifInterface
.getAttribute(ExifInterface.TAG_MAKE);
String FModel = exifInterface
.getAttribute(ExifInterface.TAG_MODEL);
String FOrientation = exifInterface
.getAttribute(ExifInterface.TAG_ORIENTATION);
String FWhiteBalance = exifInterface
.getAttribute(ExifInterface.TAG_WHITE_BALANCE);

Log.i(TAG, "FFNumber:" + FFNumber);
Log.i(TAG, "FDateTime:" + FDateTime);
Log.i(TAG, "FExposureTime:" + FExposureTime);
Log.i(TAG, "FFlash:" + FFlash);
Log.i(TAG, "FFocalLength:" + FFocalLength);
Log.i(TAG, "FImageLength:" + FImageLength);
Log.i(TAG, "FImageWidth:" + FImageWidth);
Log.i(TAG, "FISOSpeedRatings:" + FISOSpeedRatings);
Log.i(TAG, "FMake:" + FMake);
Log.i(TAG, "FModel:" + FModel);
Log.i(TAG, "FOrientation:" + FOrientation);
Log.i(TAG, "FWhiteBalance:" + FWhiteBalance);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});

获得数据:

操作Exif

上面提到,获取与设置图片的Exif信息,使用到的ExifInterface中的方法,上面已经列举出来了,主要是通过tag指定存储。

这里说明一下,Exif信息在图片中以二进制的形式存储,每个字段存储的数据位数是固定的,并且tag的数量也是固定,所以我们只能操作图片 Exif信息中已经存在的tag的值,并且保存的数据要依照它存储位数的限制,如果存储的数据类型错误,将会导致存储的数据可能无法正确的取出,超出位数 将被截取。如无法将TAG_ORIENTATION中存储一个字符串的数据,它必须存储int类型的值,多出来的将被截取。

还有一点需要注意的,saveAttributes()方法主要用于把内存中所有当前Exif信息保存到目标图片中,依照官方文档的解释,它是 一个低效率的,它会把图片的所有Exif信息,重新依次保存到目标图片,所以推荐使用setAttribute()方法进行设置Exif信息。但是在实际 应用中发现,如果仅使用setAttribute()设置Exif信息,将不会写入到目标图片中,只有在改变Exif信息后,调用 saveAttribute()才可以把新的Exif写入到目标图片中。这个过程效率比较低,模拟器上会卡顿一下,但是真机测试没有这样的情况,反应很 快。

下面通过一个简单的Demo来演示Exif的保存于读取:

btn_saveExif.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
try {
// tag
String strAttr = et_attr.getText().toString().trim();
// tag-value
String strValue = et_value.getText().toString().trim();

if (TextUtils.isEmpty(strAttr)
|| TextUtils.isEmpty(strValue)) {
Toast.makeText(MainActivity.this, "请填写属性及值",
Toast.LENGTH_SHORT).show();
return;
}
// 获取图片Exif
ExifInterface exif = new ExifInterface("/sdcard/a.jpg");
// 保存指定tag的值
exif.setAttribute(strAttr,strValue);
// 把Exif信息写入目标图片
exif.saveAttributes();
Toast.makeText(MainActivity.this, "Exif信息保存成功",
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
});
btn_readExif.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
try {
// tag
String strAttr = et_attr.getText().toString().trim();

if (TextUtils.isEmpty(strAttr)) {
Toast.makeText(MainActivity.this, "请填写属性",
Toast.LENGTH_SHORT).show();
return;
}

// 获取图片Exif
ExifInterface exif = new ExifInterface("/sdcard/a.jpg");
// 获取指定tag的属性值
String strValue = exif.getAttribute(strAttr);
if (!TextUtils.isEmpty(strValue)) {
Toast.makeText(MainActivity.this, strAttr+"="+strValue,
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "图片Exif中没有属性值为"+strAttr+"的信息",
Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
});

效果展示,先读取Make信息,再写入Make信息并重新读取:

注意,上面示例中,如果Attribute写任意值,会提示保存成功,但是并没有写入到目标图片的Exif信息当中。

 

源码下载

 

总结

以上就是Exif的所有信息,其实很好理解,就是图片中蕴含的一些拍摄环境的信息。如果开发一款与摄影相关的软件,Exif的信息应该是会用的到的。

[转载]关于自定义标题-Android开发进阶&经验分享-eoe Android开发者社区_Android开发论坛

mikel阅读(877)

[转载]关于自定义标题-Android开发进阶&经验分享-eoe Android开发者社区_Android开发论坛.

一般情况下,自定义标题时,按以下写法即可

代码片段,双击复制
01
02
03
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); //声明使用自定义标题
setContentView(R.layout.list);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);//自定义布局赋值

但是如果遇到特殊的Activity,如ListActivity,不需要setContentView,此时,如果直接把setContentView去掉,那么自定义的标题就会也不显示了。


如果依然调用setContentView,传入一个空的布局文件,我得到了一个报错信息:

布局中必须要有个id为@Android:id/list的listview的listview
于是在空布局中加入个空listview,id为@Android:id/list的listview

代码片段,双击复制
01
02
03
04
05
06
07
08
09
10
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <ListView android:id="@android:id/list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"></ListView>
 
</LinearLayout>


然后再调用setcontentview(R.layout.empty_list);

代码片段,双击复制
01
02
03
04
05
06
07
08
09
10
11
        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); //声明使用自定义标题
                setContentView(R.layout.list);
                getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);//自定义布局赋值
 
                ArrayList<Map<String,String>> a = new ArrayList<Map<String,String>>();
                Map<String,String> b = new HashMap<String,String>();
                b.put("aaa", "aaa");
                a.add(b);
 
                setListAdapter(new SimpleAdapter(this,a, R.layout.title,
                                new String[]{"aaa"}, new int[]{R.id.textView1}));


这样就ok了