楼主: 熊猫儿

[转载] 【Android开发网上的一些重要知识点[经验分享]。。】

[复制链接]
论坛徽章:
1682
九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-27 15:37:10九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55玉石琵琶
日期:2014-06-26 16:52:29玉石琵琶
日期:2014-06-26 16:52:29
91#
 楼主| 发表于 2013-1-30 09:25 | 只看该作者
七、运行Android模拟器

1.要手动运行模拟器,首先需要设置一些环境变量,这可以通过前面编译android前我们执行的两个命令来为我们设置好:

source build/envsetup.sh

lunch

其中lunch指定的选项必须跟编译Android时指定的一样,这里,我还是选择默认的第一项,即generic-eng。



2.启动模拟器

emulator



3.上面我们直接执行emulator即可运行模拟器启动Android,这时使用的默认Linux内核和默认Android系统,如果我们想自己指定要使用的Linux内核和Android系统,可以使用以下参数(见emulator -help):

    -kernel <file>                指定要使用的内核镜像

    -system <file>                指定要使用的system.img

    -ramdisk <file>               指定要使用的ramdisk.img

    -data <file>                  指定要使用的userdata.img

使用道具 举报

回复
论坛徽章:
1682
九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-27 15:37:10九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55玉石琵琶
日期:2014-06-26 16:52:29玉石琵琶
日期:2014-06-26 16:52:29
92#
 楼主| 发表于 2013-1-31 11:06 | 只看该作者
Android架构分析之Android驱动程序开发

作者:刘昊昱

博客:http://blog.csdn.net/liuhaoyutz

Android版本:2.3.7_r1

Linux内核版本:android-goldfish-2.6.29



本文介绍如何开发Android驱动程序并进行测试。



一、Android驱动程序开发

Android是基于Linux的,所以Android驱动程序的开发方法与Linux驱动程序开发方法相同。

下面我们通过一个例子程序来熟悉一下Android驱动程序的开发,这里只是一个简单的说明,如果你对Linux驱动开发也不熟悉,可以学习《Linux Device Driver》或参考的我博客的《LDD3源码分析》系列文章。

首先我们在Android内核源码的drivers目录下创建一个新的目录example,我们的驱动程序源码就放在这个目录下:

# mkdir drivers/example

# cd drivers/example



创建example.h文件,其内容如下:

[cpp] view plaincopy
1#ifndef _EXAMPLE_H_  
2#define _EXAMPLE_H_  
3  
4#include <linux/cdev.h>  
5#include <linux/semaphore.h>  
6  
7#define EXAMPLE_DEVICE_NODE_NAME  "example"  
8#define EXAMPLE_DEVICE_FILE_NAME  "example"  
9#define EXAMPLE_DEVICE_PROC_NAME  "example"  
10#define EXAMPLE_DEVICE_CLASS_NAME "example"  
11#define EXAMPLE_MAJOR 0  
12  
13struct example_dev {  
14    struct semaphore sem;  
15    struct cdev cdev;  
16    int val;  
17};  
18  
19#endif  
该头文件中定义了驱动程序中将用到的一些宏,并定义了设备结构体example_dev,该结构体的成员sem用于保证对设备的同步访问,cdev表示该设备是Linux设备驱动中的字符设备,val则代表该设备中的一个寄存器,我们这个驱动程序的作用就是给用户层应用程序提供读写这个val寄存器的方法。

使用道具 举报

回复
论坛徽章:
1682
九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-27 15:37:10九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55玉石琵琶
日期:2014-06-26 16:52:29玉石琵琶
日期:2014-06-26 16:52:29
93#
 楼主| 发表于 2013-1-31 11:06 | 只看该作者
创建example.c文件,其内容如下:

[cpp] view plaincopy
  1#include <linux/init.h>  
  2#include <linux/module.h>  
  3#include <linux/types.h>  
  4#include <linux/fs.h>  
  5#include <linux/proc_fs.h>  
  6#include <linux/device.h>  
  7#include <asm/uaccess.h>  
  8  
  9#include "example.h"  
10  
11static int example_major = EXAMPLE_MAJOR;  
12static int example_minor = 0;  
13  
14static struct class* example_class = NULL;  
15static struct example_dev* example_dev = NULL;  
16  
17module_param(example_major, int, S_IRUGO);  
18module_param(example_minor, int, S_IRUGO);  
19  
20static int example_open(struct inode* inode, struct file* filp)  
21{  
22    struct example_dev* dev;  
23  
24    /*
25     * 取得设备结构体example_dev,保存在filp私有数据区中,以方便其它函数使用。
26     */  
27    dev = container_of(inode->i_cdev, struct example_dev, cdev);  
28    filp->private_data = dev;  
29  
30    return 0;  
31}  
32  
33static int example_release(struct inode* inode, struct file* filp)  
34{  
35    return 0;  
36}  
37  
38static ssize_t example_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos)  
39{  
40    struct example_dev* dev = filp->private_data;  
41    ssize_t retval = 0;  
42  
43    /*
44     * 加锁
45     */  
46    if(down_interruptible(&(dev->sem)))  
47        return -ERESTARTSYS;  
48  
49    if(count < sizeof(dev->val))  
50        goto out;  
51  
52    /*
53     * 读寄存器的值到用户空间。
54     */  
55    if(copy_to_user(buf, &(dev->val), sizeof(dev->val)))  
56    {  
57        retval = -EFAULT;  
58        goto out;  
59    }  
60  
61    retval = sizeof(dev->val);  
62  
63out:  
64    /*
65     * 解锁
66     */  
67    up(&(dev->sem));  
68    return retval;  
69}  
70  
71static ssize_t example_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos)  
72{  
73    struct example_dev* dev = filp->private_data;  
74    ssize_t retval = 0;  
75  
76    /*
77     * 加锁
78     */  
79    if(down_interruptible(&(dev->sem)))  
80        return -ERESTARTSYS;  
81  
82    if(count != sizeof(dev->val))  
83        goto out;  
84  
85    /*
86     * 从用户空间读取并给寄存器赋值。
87     */  
88    if(copy_from_user(&(dev->val), buf, count))  
89    {  
90        retval = -EFAULT;  
91        goto out;  
92    }  
93  
94    retval = sizeof(dev->val);  
95  
96out:  
97    /*
98     * 解锁
99     */  
100    up(&(dev->sem));  
101    return retval;  
102}  
103  
104/*
105 * 设备操作函数集
106 */  
107static struct file_operations example_fops =  
108{  
109    .owner = THIS_MODULE,  
110    .open = example_open,  
111    .release = example_release,  
112    .read = example_read,  
113    .write = example_write,  
114};  
115  
116  
117/*
118 * 在同步状态下读取寄存器的值。
119 */  
120static ssize_t __example_get_val(struct example_dev* dev, char* buf)  
121{  
122    int val = 0;  
123  
124    if(down_interruptible(&(dev->sem)))  
125        return -ERESTARTSYS;  
126  
127    val = dev->val;  
128    up(&(dev->sem));  
129  
130    return snprintf(buf, 30, "%d\n", val);  
131}  
132  
133/*
134 * 在同步状态下设置寄存器的值。
135 */  
136static ssize_t __example_set_val(struct example_dev* dev, const char* buf, size_t count)  
137{  
138    int val = 0;  
139  
140    val = (int)simple_strtol(buf, NULL, 10);  
141  
142    if(down_interruptible(&(dev->sem)))  
143        return -ERESTARTSYS;  
144  
145    dev->val = val;  
146    up(&(dev->sem));  
147  
148    return count;  
149}  
150  
151/*
152 * 对属性文件的读取操作函数。
153 */  
154static ssize_t example_val_show(struct device* dev, struct device_attribute* attr, char* buf)  
155{  
156    struct example_dev* hdev = (struct example_dev*)dev_get_drvdata(dev);  
157  
158    return __example_get_val(hdev, buf);  
159}  
160  
161/*
162 * 对属性文件的写操作函数。
163 */  
164static ssize_t example_val_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count)  
165{  
166    struct example_dev* hdev = (struct example_dev*)dev_get_drvdata(dev);  
167  
168    return __example_set_val(hdev, buf, count);  
169}  
170  
171/*
172 * DEVICE_ATTR宏展开后生成的是dev_attr_val。
173 * 指定属性名为"val“,对应的读写函数分别是example_val_show和example_val_store。
174 */  
175static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, example_val_show, example_val_store);  
176  
177/*
178 * /proc节点的读操作函数。

使用道具 举报

回复
论坛徽章:
1682
九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-27 15:37:10九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55玉石琵琶
日期:2014-06-26 16:52:29玉石琵琶
日期:2014-06-26 16:52:29
94#
 楼主| 发表于 2013-1-31 11:06 | 只看该作者
179 */  
180static ssize_t example_proc_read(char* page, char** start, off_t off, int count, int* eof, void* data)  
181{  
182    if(off > 0)  
183    {  
184        *eof = 1;  
185        return 0;  
186    }  
187  
188    return __example_get_val(example_dev, page);  
189}  
190  
191/*
192 * /proc节点的写操作函数。
193 */  
194static ssize_t example_proc_write(struct file* filp, const char __user *buff, unsigned long len, void* data)  
195{  
196    int err = 0;  
197    char* page = NULL;  
198  
199    if(len > PAGE_SIZE)  
200    {  
201        printk(KERN_ALERT"The buff is too large: %lu.\n", len);  
202        return -EFAULT;  
203    }  
204  
205    page = (char*)__get_free_page(GFP_KERNEL);  
206    if(!page)  
207    {  
208        printk(KERN_ALERT"Failed to alloc page.\n");  
209        return -ENOMEM;  
210    }  
211  
212    if(copy_from_user(page, buff, len))  
213    {  
214        printk(KERN_ALERT"Failed to copy buff from user.\n");  
215        err = -EFAULT;  
216        goto out;  
217    }  
218  
219    err = __example_set_val(example_dev, page, len);  
220  
221out:  
222    free_page((unsigned long)page);  
223    return err;  
224}  
225  
226/*
227 * 创建/proc节点
228 */  
229static void example_create_proc(void)  
230{  
231    struct proc_dir_entry* entry;  
232  
233    entry = create_proc_entry(EXAMPLE_DEVICE_PROC_NAME, 0, NULL);  
234    if(entry)  
235    {  
236        entry->owner = THIS_MODULE;  
237        entry->read_proc = example_proc_read;  
238        entry->write_proc = example_proc_write;  
239    }  
240}  
241  
242/*
243 * 删除/proc节点
244 */  
245static void example_remove_proc(void)  
246{  
247    remove_proc_entry(EXAMPLE_DEVICE_PROC_NAME, NULL);  
248}  
249  
250/*
251 * 初始化设备结构体example_dev。
252 */  
253static int  __example_setup_dev(struct example_dev* dev)  
254{  
255    int retval;  
256  
257    /*
258     * 取得设备编号
259     */  
260    dev_t devno = MKDEV(example_major, example_minor);  
261  
262    /*
263     * 将设备结构体内存空间初始化为0。
264     */  
265    memset(dev, 0, sizeof(struct example_dev));  
266  
267    /*
268     * 初始化设备结构体的cdev成员,指定owner和操作函数集。
269     */  
270    cdev_init(&(dev->cdev), &example_fops);  
271    dev->cdev.owner = THIS_MODULE;  
272    dev->cdev.ops = &example_fops;  
273  
274    /*
275     * 调用cdev_add,通知内核该字符设备的存在。
276     */  
277    retval = cdev_add(&(dev->cdev),devno, 1);  
278    if(retval)  
279    {  
280        return retval;  
281    }  
282  
283    /*
284     * 初始化信号量
285     */  
286    init_MUTEX(&(dev->sem));  
287  
288    /*
289     *将寄存器val值初始化为0
290     */  
291    dev->val = 0;  
292  
293    return 0;  
294}  
295  
296/*
297 * 模块初始化函数。
298 */  
299static int __init example_init(void)  
300{  
301    int retval = -1;  
302    dev_t dev = 0;  
303    struct device* device = NULL;  
304  
305    printk(KERN_ALERT"Initializing example device.\n");  
306  
307    /*
308     * 如果用户指定了主设备号,即example_major不为0,则调用
309     * register_chrdev_region分配指定的设备编号。
310     * 如果用户没有指定主设备号,即example_major为0,则调用
311     * alloc_chrdev_region动态分配设备编号。
312     */  
313    if (example_major) {  
314        dev = MKDEV(example_major, example_minor);  
315        retval = register_chrdev_region(dev, 1, EXAMPLE_DEVICE_NODE_NAME);  
316    } else {  
317        retval = alloc_chrdev_region(&dev, example_minor, 1, EXAMPLE_DEVICE_NODE_NAME);  
318    }  
319    if (retval < 0) {  
320        printk(KERN_WARNING "can't get example_major %d\n", example_major);  
321        goto fail;  
322    }  
323  
324    /*
325     * 取得主设备号和次设备号
326     */  
327    example_major = MAJOR(dev);  
328    example_minor = MINOR(dev);  
329  
330    /*
331     * 为设备结构体example_dev动态分配内存空间。
332     */  
333    example_dev = kmalloc(sizeof(struct example_dev), GFP_KERNEL);  
334    if(!example_dev)  
335    {  
336        retval = -ENOMEM;  
337        printk(KERN_ALERT"Failed to alloc example_dev.\n");  
338        goto unregister;  
339    }  

使用道具 举报

回复
论坛徽章:
1682
九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-27 15:37:10九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55玉石琵琶
日期:2014-06-26 16:52:29玉石琵琶
日期:2014-06-26 16:52:29
95#
 楼主| 发表于 2013-1-31 11:06 | 只看该作者
340  
341    /*
342     * 调用__example_setup_dev函数对example_dev结构体进行初始化。
343     */  
344    retval = __example_setup_dev(example_dev);  
345    if(retval)  
346    {  
347        printk(KERN_ALERT"Failed to setup dev: %d.\n", retval);  
348        goto cleanup;  
349    }  
350  
351    /*
352     * 创建类example,class_create函数执行成功后,在/sys/class目录下
353     * 就会出现一个名为example的目录。
354     */  
355    example_class = class_create(THIS_MODULE, EXAMPLE_DEVICE_CLASS_NAME);  
356    if(IS_ERR(example_class))  
357    {  
358        retval = PTR_ERR(example_class);  
359        printk(KERN_ALERT"Failed to create example class.\n");  
360        goto destroy_cdev;  
361    }  
362  
363    /*
364     * 创建设备,device_create函数执行成功后,会生成/dev/example文件
365     * 和/sys/class/example/example目录及相关文件。
366     * 注意device的类型是struct device,代表一个设备。
367     */  
368    device = device_create(example_class, NULL, dev, "%s", EXAMPLE_DEVICE_FILE_NAME);  
369    if(IS_ERR(device))  
370    {  
371        retval = PTR_ERR(device);  
372        printk(KERN_ALERT"Failed to create example device.");  
373        goto destroy_class;  
374    }  
375  
376    /*
377     * 创建属性文件,对应的属性操作函数由dev_attr_val指定。
378     */  
379    retval = device_create_file(device, &dev_attr_val);  
380    if(retval < 0)  
381    {  
382        printk(KERN_ALERT"Failed to create attribute val.");  
383        goto destroy_device;  
384    }  
385  
386    /*
387     * 将example_dev保存在设备私有数据区中。
388     */  
389    dev_set_drvdata(device, example_dev);  
390  
391    /*
392     * 创建proc节点。
393     */  
394    example_create_proc();  
395  
396    printk(KERN_ALERT"Succedded to initialize example device.\n");  
397    return 0;  
398  
399destroy_device:  
400    device_destroy(example_class, dev);  
401  
402destroy_class:  
403    class_destroy(example_class);  
404  
405destroy_cdev:  
406    cdev_del(&(example_dev->cdev));  
407  
408cleanup:  
409    kfree(example_dev);  
410  
411unregister:  
412    unregister_chrdev_region(MKDEV(example_major, example_minor), 1);  
413  
414fail:  
415    return retval;  
416}  
417  
418/*
419 * 模块清理函数。
420 */  
421static void __exit example_exit(void)  
422{  
423    dev_t dev = MKDEV(example_major, example_minor);  
424  
425    printk(KERN_ALERT"Destroy example device.\n");  
426  
427    example_remove_proc();  
428  
429    if(example_class)  
430    {  
431        device_destroy(example_class, MKDEV(example_major, example_minor));  
432        class_destroy(example_class);  
433    }  
434  
435    if(example_dev)  
436    {  
437        cdev_del(&(example_dev->cdev));  
438        kfree(example_dev);  
439    }  
440  
441    unregister_chrdev_region(dev, 1);  
442}  
443  
444MODULE_LICENSE("GPL");  
445  
446module_init(example_init);  
447module_exit(example_exit);  

使用道具 举报

回复
论坛徽章:
1682
九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-27 15:37:10九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55玉石琵琶
日期:2014-06-26 16:52:29玉石琵琶
日期:2014-06-26 16:52:29
96#
 楼主| 发表于 2013-1-31 11:07 | 只看该作者
代码中的注释已经很详细,这里再简单说一下:

20 - 114行,定义了example_open、example_release、example_read、example_write这4个函数,并将这4个函数赋值给file_operations结构体变量example_fops,应用程序通过/dev/example设备节点访问设备时,就会相应调用到这几个函数。

117 - 175行,定义了通过/sys/class/example/example/val对设备进行访问时,相应会调用的函数。

177 - 248行,定义了通过/proc/example对设备进行访问时,需要调用的函数。



有了源码,下面我们需要编写一个Makefile,对这些源码进行编译。

Makefile内容如下:

[cpp] view plaincopy
obj-y += example.o  
为什么Makefile能只有这一行,大家可以参考LDD3第29页的介绍,另外也可以参考我的博客文章LDD3源码分析之hello.c与Makefile模板。

下面我们需要通知内核我们增加了一个新的驱动程序example,以便在编译内核时会对example进行编译。通知内核的方法是修改内核drivers目录下的Makefile,在该文件的最后增加一句:

[cpp] view plaincopy
obj-y               += example/  
为什么增加这一句就能通知内核呢?这个是Linux内核编译机制决定的,如果展开分析会包括很多内容,这里不再细述。大家先知道这么改就可以了。

使用道具 举报

回复
论坛徽章:
1682
九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-27 15:37:10九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55玉石琵琶
日期:2014-06-26 16:52:29玉石琵琶
日期:2014-06-26 16:52:29
97#
 楼主| 发表于 2013-1-31 11:07 | 只看该作者
以上工作完成后,我们就可以重新编译Linux内核了,回到内核根目录下,执行如下命令:

make

编译成功后得到的内核镜像就已经包括了我们加入的example驱动了。

下面我们来测试一下新加入的example驱动程序是否工作正常。

首先用我们新编译出来的Linux内核启动Android模拟器:

# source build/envsetup.sh

# lunch

# emulator -kernel kernel/goldfish/arch/arm/boot/zImage

# adb shell

进入系统后,可以看到example驱动程序创建的设备节点:/dev/example、/proc/example以及/sys/devices/virtual/example/example目录。

执行如下命令:

# cat /proc/example

0

# echo 5 > /proc/example

# cat /proc/example

5

可以看到,我们可以通过/proc/example节点访问设备寄存器。

# cat /sys/class/example/example/val

5

# echo 6 > /sys/class/example/example/val

# cat /sys/class/example/example/val

6

可以看到,我们可以通过/sys/class/example/example/val节点访问设备寄存器。

我们也可以通过/dev/example节点对设备寄存器进行访问,下一篇博客中我们将写一个C程序通过/dev/example节点访问设备寄存器,同时演示Android系统下开发C程序的步骤。

使用道具 举报

回复
论坛徽章:
1682
九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-27 15:37:10九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55玉石琵琶
日期:2014-06-26 16:52:29玉石琵琶
日期:2014-06-26 16:52:29
98#
 楼主| 发表于 2013-2-1 09:39 | 只看该作者
本帖最后由 熊猫儿 于 2013-2-1 09:53 编辑

android Bitmap效果处理 (2012-10-18 10:35:29)转载

标签: 杂谈
分类: android学习

Android中图片的处理(放大缩小,去色,转换格式,增加水印等),多张图片四个方位的图片合成,改变bitmap大小,图片去色等功能  
Java代码
package com.dzh.operateimage;   
import android.graphics.Bitmap;   
import android.graphics.Bitmap.Config;   
import android.graphics.BitmapFactory;   
import android.graphics.Canvas;   
import android.graphics.ColorMatrix;   
import android.graphics.ColorMatrixColorFilter;   
import android.graphics.Paint;   
import android.graphics.PorterDuff.Mode;   
import android.graphics.PorterDuffXfermode;   
import android.graphics.Rect;   
import android.graphics.RectF;   
import android.graphics.drawable.BitmapDrawable;   
import android.graphics.drawable.Drawable;   
import java.io.ByteArrayOutputStream;   
import java.io.File;   
import java.io.FileNotFoundException;   
import java.io.FileOutputStream;   
import java.io.IOException;   
  
public class ImageTools {   
public static final int LEFT = 0;   
public static final int RIGHT = 1;   
public static final int TOP = 3;   
public static final int BOTTOM = 4;  

  
  
public static Bitmap toGrayscale(Bitmap bmpOriginal) {   
int width, height;   
height = bmpOriginal.getHeight();   
width = bmpOriginal.getWidth();   
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);   
Canvas c = new Canvas(bmpGrayscale);   
Paint paint = new Paint();   
ColorMatrix cm = new ColorMatrix();   
cm.setSaturation(0);   
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);   
paint.setColorFilter(f);   
c.drawBitmap(bmpOriginal, 0, 0, paint);   
return bmpGrayscale;   
}
   
  

public static Bitmap toGrayscale(Bitmap bmpOriginal, int pixels) {   
return toRoundCorner(toGrayscale(bmpOriginal), pixels);   
}
   
  
  
public static Bitmap toRoundCorner(Bitmap bitmap, int pixels) {   
Bitmap output = Bitmap   
.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);   
Canvas canvas = new Canvas(output);   
final int color = 0xff424242;   
final Paint paint = new Paint();   
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());   
final RectF rectF = new RectF(rect);   
final float roundPx = pixels;   
paint.setAntiAlias(true);   
canvas.drawARGB(0, 0, 0, 0);   
paint.setColor(color);   
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);   
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));   
canvas.drawBitmap(bitmap, rect, rect, paint);   
return output;   
}
   

使用道具 举报

回复
论坛徽章:
1682
九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-27 15:37:10九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55玉石琵琶
日期:2014-06-26 16:52:29玉石琵琶
日期:2014-06-26 16:52:29
99#
 楼主| 发表于 2013-2-1 09:55 | 只看该作者
本帖最后由 熊猫儿 于 2013-2-1 09:57 编辑

public static BitmapDrawable toRoundCorner(BitmapDrawable bitmapDrawable, int pixels) {   
Bitmap bitmap = bitmapDrawable.getBitmap();   
bitmapDrawable = new BitmapDrawable(toRoundCorner(bitmap, pixels));   
return bitmapDrawable;   
}
   
  
public static void saveBefore(String path) {   
BitmapFactory.Options options = new BitmapFactory.Options();   
options.inJustDecodeBounds = true;   
// 获取这个图片的宽和高   
Bitmap bitmap = BitmapFactory.decodeFile(path, options); // 此时返回bm为空   
options.inJustDecodeBounds = false;   
// 计算缩放比   
int be = (int)(options.outHeight / (float)200);   
if (be <= 0)   
be = 1;   
options.inSampleSize = 2; // 图片长宽各缩小二分之一   
// 重新读入图片,注意这次要把options.inJustDecodeBounds 设为 false哦   
bitmap = BitmapFactory.decodeFile(path, options);   
int w = bitmap.getWidth();   
int h = bitmap.getHeight();   
System.out.println(w + " " + h);   
// savePNG_After(bitmap,path);   
saveJPGE_After(bitmap, path);   
}
   
  
public static void savePNG_After(Bitmap bitmap, String name) {   
File file = new File(name);   
try {   
FileOutputStream out = new FileOutputStream(file);   
if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)) {   
out.flush();   
out.close();   
}   
} catch (FileNotFoundException e) {   
e.printStackTrace();   
} catch (IOException e) {   
e.printStackTrace();   
}   
}
   
  
public static void saveJPGE_After(Bitmap bitmap, String path) {   
File file = new File(path);   
try {   
FileOutputStream out = new FileOutputStream(file);   
if (bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out)) {   
out.flush();   
out.close();   
}   
} catch (FileNotFoundException e) {   
e.printStackTrace();   
} catch (IOException e) {   
e.printStackTrace();   
}   
}
   

public static Bitmap createBitmapForWatermark(Bitmap src, Bitmap watermark) {   
if (src == null) {   
return null;   
}   
int w = src.getWidth();   
int h = src.getHeight();   
int ww = watermark.getWidth();   
int wh = watermark.getHeight();   
// create the new blank bitmap   
Bitmap newb = Bitmap.createBitmap(w, h, Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图   
Canvas cv = new Canvas(newb);   
// draw src into   
cv.drawBitmap(src, 0, 0, null);// 在 0,0坐标开始画入src   
// draw watermark into   
cv.drawBitmap(watermark, w - ww + 5, h - wh + 5, null);// 在src的右下角画入水印   
// save all clip   
cv.save(Canvas.ALL_SAVE_FLAG);// 保存   
// store   
cv.restore();// 存储   
return newb;   
}
   
  
public static Bitmap potoMix(int direction, Bitmap... bitmaps) {   
if (bitmaps.length <= 0) {   
return null;   
}   
if (bitmaps.length == 1) {   
return bitmaps[0];   
}   
Bitmap newBitmap = bitmaps[0];   
// newBitmap = createBitmapForFotoMix(bitmaps[0],bitmaps[1],direction);   
for (int i = 1; i < bitmaps.length; i++) {   
newBitmap = createBitmapForFotoMix(newBitmap, bitmaps, direction);   
}   
return newBitmap;   
}   
  
private static Bitmap createBitmapForFotoMix(Bitmap first, Bitmap second, int direction) {   
if (first == null) {   
return null;   
}   
if (second == null) {   
return first;   
}   
int fw = first.getWidth();   
int fh = first.getHeight();   
int sw = second.getWidth();   
int sh = second.getHeight();   
Bitmap newBitmap = null;   
if (direction == LEFT) {   
newBitmap = Bitmap.createBitmap(fw + sw, fh > sh ? fh : sh, Config.ARGB_8888);   
Canvas canvas = new Canvas(newBitmap);   
canvas.drawBitmap(first, sw, 0, null);   
canvas.drawBitmap(second, 0, 0, null);   
} else if (direction == RIGHT) {   
newBitmap = Bitmap.createBitmap(fw + sw, fh > sh ? fh : sh, Config.ARGB_8888);   
Canvas canvas = new Canvas(newBitmap);   
canvas.drawBitmap(first, 0, 0, null);   
canvas.drawBitmap(second, fw, 0, null);   
} else if (direction == TOP) {   
newBitmap = Bitmap.createBitmap(sw > fw ? sw : fw, fh + sh, Config.ARGB_8888);   
Canvas canvas = new Canvas(newBitmap);   
canvas.drawBitmap(first, 0, sh, null);   
canvas.drawBitmap(second, 0, 0, null);   
} else if (direction == BOTTOM) {   
newBitmap = Bitmap.createBitmap(sw > fw ? sw : fw, fh + sh, Config.ARGB_8888);   
Canvas canvas = new Canvas(newBitmap);   
canvas.drawBitmap(first, 0, 0, null);   
canvas.drawBitmap(second, 0, fh, null);   
}   
return newBitmap;   
}   
  
public static Bitmap createBitmapBySize(Bitmap bitmap,int width,int height)   
{   
return Bitmap.createScaledBitmap(bitmap, width, height, true);   
}   
  
public static Bitmap drawableToBitmapByBD(Drawable drawable) {   
BitmapDrawable bitmapDrawable = (BitmapDrawable)drawable;   
return bitmapDrawable.getBitmap();   
}   
  
public static Drawable bitmapToDrawableByBD(Bitmap bitmap) {   
Drawable drawable = new BitmapDrawable(bitmap);   
return drawable;   
}   
  
public static Bitmap bytesToBimap(byte[] b) {   
if (b.length != 0) {   
return BitmapFactory.decodeByteArray(b, 0, b.length);   
} else {   
return null;   
}   
}   
  
public static byte[] bitmapToBytes(Bitmap bm) {   
ByteArrayOutputStream baos = new ByteArrayOutputStream();   
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);   
return baos.toByteArray();   
}   
}

文章出处:
本篇文章来源于 Linux公社网站(www.linuxidc.com)  原文链接:http://www.linuxidc.com/Linux/2011-11/48110.htm

使用道具 举报

回复
论坛徽章:
1682
九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-27 15:37:10九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55九尾狐狸
日期:2012-09-19 11:12:55玉石琵琶
日期:2014-06-26 16:52:29玉石琵琶
日期:2014-06-26 16:52:29
100#
 楼主| 发表于 2013-2-1 09:56 | 只看该作者
Android游戏开发之一】设置全屏以及绘画简单的图形
(2013-01-22 14:16:16)
转载▼
标签:
android
学习笔记
it
分类: Android游戏开发学习笔记

转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/android-game/263.html
这一章简单讲述些简单的Android-UI:

直接上代码:
package com.himi;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        //隐去电池等图标和一切修饰部分(状态栏部分)
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        // 隐去标题栏(程序的名字)
        setContentView(new MyView(this));
    }
}
注意: 隐去标题(应用的名字) 此设定必须要写在setContentView之前,否则会有异常!

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表