讨论
http://www.cnblogs.com/delonchen/archive/2011/06/12/CGContextDrawImage.html
这个函数绘制图片,但坐标系统原点在左上角,y方向向下的(坐标系A),但在Quartz中坐标系原点在左下角,y方向向上的(坐标系B)。图片绘制也是颠倒的。
要达到预想的效果必须变换坐标系,代码如下:
void drawImage(CGContextRef context, CGImageRef image , CGRect rect){
CGContextSaveGState(context);
CGContextTranslateCTM(context, rect.origin.x, rect.origin.y);//4
CGContextTranslateCTM(context, 0, rect.size.height);//3
CGContextScaleCTM(context, 1.0, -1.0);//2
CGContextTranslateCTM(context, -rect.origin.x, -rect.origin.y);//1
CGContextDrawImage(context, rect, image);
CGContextRestoreGState(context);
}
A到B变换 通过1->2->3->4步骤实现的,这样好理解些
通常我会用UIImage drawInRect实现想要的功能。
我们在使用“CGContextShowTextAtPoint”,经常会遇到字体翻转问题。CGContextShowTextAtPoint word upside.
这个问题可以通过
CGContextTranslateCTM(ctx, 0, imageSize.height);
CGContextScaleCTM(ctx, 1, -1);
解决。
不过要是想继续正常绘制其他内容,我们可以采用先存储后恢复的方式
CGAffineTransform normalState=CGContextGetCTM(context);
CGContextTranslateCTM(ctx, 0, imageSize.height);
CGContextScaleCTM(ctx, 1, -1);
CGContextConcatCTM(context, normalState);
- (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); CGContextTranslateCTM(context, 0, rect.size.height); CGContextScaleCTM(context, 1.0, -1.0); int firstCol = floorf(CGRectGetMinX(rect) / tileSize); int lastCol = floorf((CGRectGetMaxX(rect)-1) / tileSize); int firstRow = floorf(CGRectGetMinY(rect) / tileSize); int lastRow = floorf((CGRectGetMaxY(rect)-1) / tileSize); for( int row = firstRow; row <= lastRow; row++ ) { for( int col = firstCol; col <= lastCol; col++ ) { UIImage = [self getTileWithRow:row column:col]; CGRect tileRect = CGRectMake((col * tileSize), row * tileSize), tileSize, tileSize); CGContextDrawImage(context, tileRect, tile.CGImage); } } CGContextRestoreGState(context); }
1.错误提示:
error: bits/predefs.h: No such file or directory In file included from /usr/include/endian.h:61, from /opt/HEPXA270/02_toolchain//usr/include/bits/waitstatus.h:65, from /usr/include/stdlib.h:43, from ../include/misc.h:143, from atom.c:57: /opt/HEPXA270/02_toolchain//usr/include/bits/byteswap.h:21:3: error: #error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead." make[1]: *** [atom.lo] Error 1 make[1]: Leaving directory `/xroot/soft/xorg-server-1.3.0.0/dix' make: *** [install-recursive] Error 1
解决方法:
解决方法:sudo apt-get install gcc-multilib
( 注:gcc-multilib主要是用于32 位系统编译 64 位程序,64 位系统编译 32 位程序,因为我在虚拟机里安装的是64位ubuntu,编译的是32位,所以会出现这种情况)
变量对每一个程序员再熟悉不过,每一个编程语言都有自己的变量,Makefile也不例外,下面就让我们来看一下Makefile怎么定义和使用变量的吧!
这里我们先写一个例子:
头文件:apute.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
第一个C文件foo.c,根据地址打印传递的字符串
#include "apute.h"
void foo(char * str)
{
printf("str is %s\n",str);
}
第二个C文件bar.c,根据传递的两个变量计算之和并打印
#include "apute.h"
void bar(int a, int b)
{
printf("a+b = %d\n",a+b);
}
第三个C文件main.c,传递参数,调用上述两个函数:
int main()
{
int a,b;
a = 11;
b = 22;
char *str = "Hello!";
foo(str);
bar(a,b);
return 0;
}
Makefile:
执行结果:
从上述例子我们可以看到,一个变量的定义很简单,就是一个名字(变量名)后面跟上一个等号,
然后在等号的后面放这个变量所期望的值。对于变量的引用,则需要采用$(变量名)或者${变量名}这种模式。
在这里我们引用了变量CC来指定编译器,引入了objects来保存.o文件,当然你也可以引入更多的变量,比如
RM=rm,用于指定删除文件的命令等等。这样引入变量,加入我们需要更改编译器,只需更改变量赋值的地方,
不必更改每一个地方,非常方便。
接下来我们看一下自动变量:
在我们编写Makefile,有些时候目标和先决条件的名字会在规则的命令中多次出现,而且,如果改变了目标或是依赖文件,
命令中就得全部跟着改。这就需要用到Makefile中的自动变量,它们包括:
-
$@用于表示一个规则中的目标。当我们的一个规则中有多个目标时,$@所指的是其中任何造成命令被运行的目标。
-
$^则表示的是规则中的所有先择条件。
-
$<表示的是规则中的第一个先决条件
执行结果是:
这里我们可以轻松的验证自动变量$@,$^,$<所指何意。
现在我们使用自动变量改写一下第一个例子,
依旧OK!这样看着多少显着有些专业点。
Makefile中还有一些特殊变量,第一个就是 MAKE 变量,它表示的是 make 命令名是什么。当我们需要在 Makefile 中调用另一个
Makefile 时需要用到这个变量,采用这种方式,有利于写一个容易移植的 Makefile。
执行结果:
MAKE = make
第二个MAKECMDGOALS,它表示当前用户输入的make目标是什么
执行结果:
从测试结果看来,MAKECMDGOALS 指的是用户输入的目标,当我们只运行 make 命令时, 虽然根据Makefile 的语法,
第一个目标将成为缺省目标,即all 目标,但MAKECMDGOALS 仍然是空,而不是 all,这一点我们需要注意。