当前位置:  编程技术>移动开发
本页文章导读:
    ▪CGAffineTransform有关函数        CGAffineTransform相关函数 CGAffineTransform rotation = CGAffineTransformMakeRotation(M_PI_2);[xxx setTransform:rotation];呵呵就这么简单的两行代码就可以实现了! 顺便记录一些常量,以后用的着! #define M_E     .........
    ▪ 有返回值的startActivity-startActivityForResult()        有返回值的startActivity---------startActivityForResult() 1 从one Activity跳到 two Activity:   startActivity(new intent(this,two.class));   但是我们想在two里加个按钮,当点击时就返回到原来的one中,   这时我们.........
    ▪ AudioQueue回实现音频播放功能时最主要的步骤       AudioQueue来实现音频播放功能时最主要的步骤 使用AudioQueue来实现音频播放功能时最主要的步骤,可以更简练的归纳如下。 1. 打开播放音频文件 2. 取得播放音频文件的数据格式 3. 准备播放用.........

[1]CGAffineTransform有关函数
    来源: 互联网  发布时间: 2014-02-18
CGAffineTransform相关函数

CGAffineTransform rotation = CGAffineTransformMakeRotation(M_PI_2);
[xxx setTransform:rotation];
呵呵就这么简单的两行代码就可以实现了!

顺便记录一些常量,以后用的着!

#define M_E         2.71828182845904523536028747135266250   e
#define M_LOG2E     1.44269504088896340735992468100189214   log 2e
#define M_LOG10E    0.434294481903251827651128918916605082  log 10e
#define M_LN2       0.693147180559945309417232121458176568  log e2
#define M_LN10      2.30258509299404568401799145468436421   log e10
#define M_PI        3.14159265358979323846264338327950288   pi
#define M_PI_2      1.57079632679489661923132169163975144   pi/2
#define M_PI_4      0.785398163397448309615660845819875721  pi/4
#define M_1_PI      0.318309886183790671537767526745028724  1/pi
#define M_2_PI      0.636619772367581343075535053490057448  2/pi
#define M_2_SQRTPI  1.12837916709551257389615890312154517   2/sqrt(pi)
#define M_SQRT2     1.41421356237309504880168872420969808   sqrt(2)
#define M_SQRT1_2   0.707106781186547524400844362104849039  1/sqrt(2)

 

 

from:http://donbe.blog.163.com/blog/static/138048021201061054243442/

CGAffineTransformMakeTranslation(width, 0.0);是改变位置的,
CGAffineTransformRotate(transform, M_PI);是旋转的。
CGAffineTransformMakeRotation(-M_PI);也是旋转的
transform = CGAffineTransformScale(transform, -1.0, 1.0);是缩放的。
view.transform = CGAffineTransformIdentity;线性代数里面讲的矩阵变换,这个是恒等变换


当你改变过一个view.transform属性或者view.layer.transform的时候需要恢复默认状态的话,记得先把他们重置可以使用view.transform = CGAffineTransformIdentity,或者view.layer.transform = CATransform3DIdentity,假设你一直不断的改变一个view.transform的属性,而每次改变之前没有重置的话,你会发现后来的改变和你想要的发生变化了,不是你真正想要的结果


Quartz转换实现的原理:Quartz把绘图分成两个部分,
    用户空间,即和设备无关,
    设备空间,
用户空间和设备空间中间存在一个转换矩阵 : CTM
本章实质是讲解CTM
 
Quartz提供的3大功能
移动,旋转,缩放
 
演示如下,首先加载一张图片
void CGContextDrawImage (
   CGContextRef c,
   CGRect rect,
   CGImageRef image
);
 
 
 
 
 
移动函数
CGContextTranslateCTM (myContext, 100, 50);
 
 
 
旋转函数
include <math.h>
static inline double radians (double degrees) {return degrees * M_PI/180;}
CGContextRotateCTM (myContext, radians(–45.));
 
 
 
缩放
CGContextScaleCTM (myContext, .5, .75);
 
 
 
翻转, 两种转换合成后的效果,先把图片移动到右上角,然后旋转180度
CGContextTranslateCTM (myContext, w,h);
CGContextRotateCTM (myContext, radians(-180.));
 
 
 
组合几个动作
CGContextTranslateCTM (myContext, w/4, 0);
CGContextScaleCTM (myContext, .25,  .5);
CGContextRotateCTM (myContext, radians ( 22.));
 
 
 
 
 
CGContextRotateCTM (myContext, radians ( 22.));
CGContextScaleCTM (myContext, .25,  .5);
CGContextTranslateCTM (myContext, w/4, 0);
 
 
 
 
上面是通过直接修改当前的ctm实现3大效果,下面是通过创建Affine Transforms,然后连接ctm实现同样的3种效果
这样做的好处是可以重用这个Affine Transforms
应用Affine Transforms 到ctm的函数
void CGContextConcatCTM (
   CGContextRef c,
   CGAffineTransform transform
);
 
 
Creating Affine Transforms
移动效果
CGAffineTransform CGAffineTransformMakeTranslation (
   CGFloat tx,
   CGFloat ty
);
 
CGAffineTransform CGAffineTransformTranslate (
   CGAffineTransform t,
   CGFloat tx,
   CGFloat ty
);
 
旋转效果
CGAffineTransform CGAffineTransformMakeRotation (
   CGFloat angle
);
 
CGAffineTransform CGAffineTransformRotate (
   CGAffineTransform t,
   CGFloat angle
);
 
缩放效果
CGAffineTransform CGAffineTransformMakeScale (
   CGFloat sx,
   CGFloat sy
);
 
CGAffineTransform CGAffineTransformScale (
   CGAffineTransform t,
   CGFloat sx,
   CGFloat sy
);
 
反转效果
CGAffineTransform CGAffineTransformInvert (
   CGAffineTransform t
);
 
只对局部产生效果
CGRect CGRectApplyAffineTransform (
   CGRect rect,
   CGAffineTransform t
);
 
判断两个AffineTrans是否相等
bool CGAffineTransformEqualToTransform (
   CGAffineTransform t1,
   CGAffineTransform t2
);
 
 
 
获得Affine Transform
CGAffineTransform CGContextGetUserSpaceToDeviceSpaceTransform (
   CGContextRef c
);
 
下面的函数只起到查看的效果,比如看一下这个用户空间的点,转换到设备空间去坐标是多少
CGPoint CGContextConvertPointToDeviceSpace (
   CGContextRef c,
   CGPoint point
);
 
CGPoint CGContextConvertPointToUserSpace (
   CGContextRef c,
   CGPoint point
);
 
CGSize CGContextConvertSizeToDeviceSpace (
   CGContextRef c,
   CGSize size
);
 
CGSize CGContextConvertSizeToUserSpace (
   CGContextRef c,
   CGSize size
);
 
CGRect CGContextConvertRectToDeviceSpace (
   CGContextRef c,
   CGRect rect
);
 
CGRect CGContextConvertRectToUserSpace (
   CGContextRef c,
   CGRect rect
);
 
 
CTM真正的数学行为
这个转换矩阵其实是一个 3x3的 举证
如下图
 
 
下面举例说明几个转换运算的数学实现
x y 是原先点的坐标
下面是从用户坐标转换到设备坐标的计算公式
 
 
 
 
下面是一个identity matrix,就是输入什么坐标,出来什么坐标,没有转换
 
最终的计算结果是 x=x,y=y,  
 
 
 可以用函数判断这个矩阵是不是一个 identity matrix
bool CGAffineTransformIsIdentity (
   CGAffineTransform t
);
 
 
 
 
参考:http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_affine/dq_affine.html








- (void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation   duration:(NSTimeInterval)duration
{
        
    
        if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
        {
                b=YES;
                
                self.view=mainvv;
                self.view.transform = CGAffineTransformIdentity;
                self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(0));
                self.view.bounds = CGRectMake(0.0, 0.0, 768.0, 1004.0);
                
        }
        else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
        {
                b=NO;
                
                self.view = self.vv;
                self.view.transform = CGAffineTransformIdentity;
                self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(-90));
                self.view.bounds = CGRectMake(0.0, 0.0, 1024.0, 748.0);
                
                
                
        }
        else if (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
        {
                
                b=YES;
                self.view=mainvv;
                self.view.transform = CGAffineTransformIdentity;
                self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(180));
                self.view.bounds = CGRectMake(0.0, 0.0, 768.0, 1004.0);
                
        }
        else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
        {
                
                b=NO;
                self.view = self.vv;
                self.view.transform = CGAffineTransformIdentity;
                self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
                self.view.bounds = CGRectMake(0.0, 0.0, 1024.0, 748.0);
                
        }
        
        
}


3

Quartz转换实现的原理:Quartz把绘图分成两个部分,
    用户空间,即和设备无关,
    设备空间,
用户空间和设备空间中间存在一个转换矩阵 : CTM
本章实质是讲解CTM

Quartz提供的3大功能
移动,旋转,缩放

演示如下,首先加载一张图片
void CGContextDrawImage (
   CGContextRef c,
   CGRect rect,
   CGImageRef image
);

 

 
移动函数
CGContextTranslateCTM (myContext, 100, 50);



旋转函数
include <math.h>
static inline double radians (double degrees) {return degrees * M_PI/180;}
CGContextRotateCTM (myContext, radians(–45.));



缩放
CGContextScaleCTM (myContext, .5, .75);




翻转, 两种转换合成后的效果,先把图片移动到右上角,然后旋转180度
CGContextTranslateCTM (myContext, w,h);
CGContextRotateCTM (myContext, radians(-180.));



组合几个动作
CGContextTranslateCTM (myContext, w/4, 0);
CGContextScaleCTM (myContext, .25,  .5);
CGContextRotateCTM (myContext, radians ( 22.));

 


CGContextRotateCTM (myContext, radians ( 22.));
CGContextScaleCTM (myContext, .25,  .5);
CGContextTranslateCTM (myContext, w/4, 0);




上面是通过直接修改当前的ctm实现3大效果,下面是通过创建Affine Transforms,然后连接ctm实现同样的3种效果
这样做的好处是可以重用这个Affine Transforms
应用Affine Transforms 到ctm的函数
void CGContextConcatCTM (
   CGContextRef c,
   CGAffineTransform transform
);


Creating Affine Transforms
移动效果
CGAffineTransform CGAffineTransformMakeTranslation (
   CGFloat tx,
   CGFloat ty
);

CGAffineTransform CGAffineTransformTranslate (
   CGAffineTransform t,
   CGFloat tx,
   CGFloat ty
);

旋转效果
CGAffineTransform CGAffineTransformMakeRotation (
   CGFloat angle
);

CGAffineTransform CGAffineTransformRotate (
   CGAffineTransform t,
   CGFloat angle
);

缩放效果
CGAffineTransform CGAffineTransformMakeScale (
   CGFloat sx,
   CGFloat sy
);

CGAffineTransform CGAffineTransformScale (
   CGAffineTransform t,
   CGFloat sx,
   CGFloat sy
);

反转效果
CGAffineTransform CGAffineTransformInvert (
   CGAffineTransform t
);

只对局部产生效果
CGRect CGRectApplyAffineTransform (
   CGRect rect,
   CGAffineTransform t
);

判断两个AffineTrans是否相等
bool CGAffineTransformEqualToTransform (
   CGAffineTransform t1,
   CGAffineTransform t2
);



获得Affine Transform
CGAffineTransform CGContextGetUserSpaceToDeviceSpaceTransform (
   CGContextRef c
);

下面的函数只起到查看的效果,比如看一下这个用户空间的点,转换到设备空间去坐标是多少
CGPoint CGContextConvertPointToDeviceSpace (
   CGContextRef c,
   CGPoint point
);

CGPoint CGContextConvertPointToUserSpace (
   CGContextRef c,
   CGPoint point
);

CGSize CGContextConvertSizeToDeviceSpace (
   CGContextRef c,
   CGSize size
);

CGSize CGContextConvertSizeToUserSpace (
   CGContextRef c,
   CGSize size
);

CGRect CGContextConvertRectToDeviceSpace (
   CGContextRef c,
   CGRect rect
);

CGRect CGContextConvertRectToUserSpace (
   CGContextRef c,
   CGRect rect
);


CTM真正的数学行为
这个转换矩阵其实是一个 3x3的 举证
如下图

下面举例说明几个转换运算的数学实现
x y 是原先点的坐标
下面是从用户坐标转换到设备坐标的计算公式


下面是一个identity matrix,就是输入什么坐标,出来什么坐标,没有转换
最终的计算结果是 x=x,y=y,

 可以用函数判断这个矩阵是不是一个 identity matrix
bool CGAffineTransformIsIdentity (
   CGAffineTransform t
);


移动矩阵


 

缩放矩阵
 

旋转矩阵
 

旋转加移动矩阵
 


    
[2] 有返回值的startActivity-startActivityForResult()
    来源: 互联网  发布时间: 2014-02-18
有返回值的startActivity---------startActivityForResult()

1 从one Activity跳到 two Activity:

 

startActivity(new intent(this,two.class));

 

但是我们想在two里加个按钮,当点击时就返回到原来的one中,

 

这时我们当然可以在点击事件中写:

 

startActivity(new intent(this,one.class));

 

但是我们还有另一种方法:

 

从one Activity跳到 two Activity:

 

startActivityResult(new intent(this,two.class),1);

 

1 是用来标记是否是这个startActivityResult的返回值的,一般情况下如果只有一个startActivityResult,没有什么作用,但是如果我们one中有两个startActivityResult,我们可以用1,2......来区分是那个startActivityResult的返回值,确定这个返回结果是谁返回的。

 

我们跳到two中了,在two里的按钮的点击事件中返回到one:

 

 this.setResult(RESULT_OK);

  this.finish();

 

这样把RESULT_OK这个值返回给了one,在one的

 protected void onActivityResult(int requestCode, int resultCode, Intent data) {}

中处理:

    @Override

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode==RESULT_OK&&requestCode==1) {

 

              //要做的事。

 

        }

    }

 

2 我们想把数据从one带到two,再从two带到one:

1 ---->2; 1中:

Intent intent = new Intent(this, Activity2.class);  

Bundle bundle = new Bundle();

bundle.putString("first", "one");

intent .putExtras(bundle); 

startActivityForResult(intent ,1);

 

2中取得1传过来的数据:

Intent intent = this.getIntent();

Bundle bundle = intent .getExtras();

String string = bundle .getString("first");

 

2的按钮的点击事件中返回1,并带着数据:

 

Intent intent = new Intent();

Bundle bundle = new Bundle();

bundle.putString("second", "two");

intent.putExtras(bundle);

this.setResult(RESULT_OK, intent);

this.finish();

 

返回1后在1中处理返回的结果和返回的数据:

  • protected void onActivityResult(int requestCode, int resultCode,  
  •                                     Intent data){  
  •         switch (resultCode){  
  •         case RESULT_OK:  
  •             Bundle bundle = data.getExtras();  
  •               
  •             String string = bundle.getString("second");  
  •               
  •             updateText(string);  
  •         }  
  •     } 
  •  

     

     

     


        
    [3] AudioQueue回实现音频播放功能时最主要的步骤
        来源: 互联网  发布时间: 2014-02-18
    AudioQueue来实现音频播放功能时最主要的步骤

    使用AudioQueue来实现音频播放功能时最主要的步骤,可以更简练的归纳如下。

    1. 打开播放音频文件
    2. 取得播放音频文件的数据格式
    3. 准备播放用的队列
    4. 将缓冲中的数据移动到队列中
    5. 开始播放
    6. 在回调函数中进行队列处理

    以下是贯彻上述六个主要步骤的代码实例,只需要向[play:]中传入音频文件的路径就可以开始音频播放。稍加修改可以直接应用到自己的程序中。

    Source Audioplay.h
    #import <Foundation/Foundation.h>
    #import <AudioToolbox/AudioToolbox.h>
    #import <AudioToolbox/AudioFile.h>

    #define NUM_BUFFERS 3


    @interface AudioPlayer : NSObject {

        //播放音频文件ID
        AudioFileID audioFile;

        //音频流描述对象
        AudioStreamBasicDescription dataFormat;

         //音频队列
        AudioQueueRef queue;

        SInt64 packetIndex;

        UInt32 numPacketsToRead;

        UInt32 bufferByteSize;

        AudioStreamPacketDescription *packetDescs;

        AudioQueueBufferRef buffers[NUM_BUFFERS];

    }

    //定义队列为实例属性

    @property AudioQueueRef queue;

    //播放方法定义

    - (void) play:(CFURLRef) path;

    //定义缓存数据读取方法

    - (void) audioQueueOutputWithQueue:(AudioQueueRef)audioQueue
                           queueBuffer:(AudioQueueBufferRef)audioQueueBuffer;

    //定义回调(Callback)函数

    static void BufferCallback(void *inUserData, AudioQueueRef inAQ,
                                                AudioQueueBufferRef buffer);

    //定义包数据的读取方法

    - (UInt32)readPacketsIntoBuffer:(AudioQueueBufferRef)buffer;

    @end

    Source Audioplay.m

    static UInt32 gBufferSizeBytes = 0x10000;


    @implementation AudioPlayer

    @synthesize queue;

    // 回调(Callback)函数的实现

    static void BufferCallback(void *inUserData, AudioQueueRef inAQ,
      AudioQueueBufferRef buffer) {
        AudioPlayer* player = (AudioPlayer*)inUserData;
        [player  audioQueueOutputWithQueue:inAQ queueBuffer:buffer];
    }

    //初始化方法(为NSObject中定义的初始化方法)

    - (id) init {
        for(int i=0; i<NUM_BUFFERS; i++) {
            AudioQueueEnqueueBuffer(queue,buffers,0,nil);
        }
        return self;
    }

    //缓存数据读取方法的实现

    - (void) audioQueueOutputWithQueue:(AudioQueueRef)audioQueue
                           queueBuffer:(AudioQueueBufferRef)audioQueueBuffer {

        OSStatus status;


        // 读取包数据
        UInt32  numBytes;

        UInt32  numPackets = numPacketsToRead;

        status = AudioFileReadPackets(
                    audioFile, NO, &numBytes, packetDescs,
                    packetIndex, &numPackets, audioQueueBuffer->mAudioData);
        // 成功读取时
        if (numPackets > 0) {

            //将缓冲的容量设置为与读取的音频数据一样大小(确保内存空间)
            audioQueueBuffer->mAudioDataByteSize = numBytes;

            // 完成给队列配置缓存的处理
            status = AudioQueueEnqueueBuffer(
                    audioQueue, audioQueueBuffer, numPackets, packetDescs);

            // 移动包的位置
            packetIndex += numPackets;
        }
    }

    //音频播放方法的实现

    -(void) play:(CFURLRef) path {

        UInt32      size, maxPacketSize;

        char        *cookie;

        int         i;

        OSStatus status;

        // 打开音频文件
        status = AudioFileOpenURL(/blog_article/path, kAudioFileReadPermission, 0, &audioFile/index.html);
        if (status != noErr) {
            // 错误处理
            return;
        }
        // 取得音频数据格式
        size = sizeof(dataFormat);
        AudioFileGetProperty(audioFile, kAudioFilePropertyDataFormat,
                                                       &size, &dataFormat);

        // 创建播放用的音频队列
        AudioQueueNewOutput(&dataFormat, BufferCallback,
                                   self, nil, nil, 0, &queue);



        //计算单位时间包含的包数
        if (dataFormat.mBytesPerPacket==0 || dataFormat.mFramesPerPacket==0) {

            size = sizeof(maxPacketSize);
            AudioFileGetProperty(audioFile,
              kAudioFilePropertyPacketSizeUpperBound, &size, &maxPacketSize);
            if (maxPacketSize > gBufferSizeBytes) {
                maxPacketSize = gBufferSizeBytes;

            }

            // 算出单位时间内含有的包数
            numPacketsToRead = gBufferSizeBytes / maxPacketSize;
            packetDescs = malloc(
              sizeof(AudioStreamPacketDescription) * numPacketsToRead);
        } else {
            numPacketsToRead = gBufferSizeBytes / dataFormat.mBytesPerPacket;
            packetDescs = nil;
        }

        //设置Magic Cookie,参见第二十七章的相关介绍
        AudioFileGetPropertyInfo(audioFile,
               kAudioFilePropertyMagicCookieData, &size, nil);
        if (size > 0) {
            cookie = malloc(sizeof(char) * size);
            AudioFileGetProperty(audioFile,
                      kAudioFilePropertyMagicCookieData, &size, cookie);
            AudioQueueSetProperty(queue,
                      kAudioQueueProperty_MagicCookie, cookie, size);
            free(cookie);
        }

        // 创建并分配缓存空间
        packetIndex = 0;

        for (i = 0; i < NUM_BUFFERS; i++) {
            AudioQueueAllocateBuffer(queue, gBufferSizeBytes, &buffers);

            //读取包数据
            if ([self readPacketsIntoBuffer:buffers] == 0) {
                break;
            }
        }

        Float32 gain = 1.0;

        //设置音量
        AudioQueueSetParameter (
                                queue,
                                kAudioQueueParam_Volume,
                                gain
                                );

        //队列处理开始,此后系统会自动调用回调(Callback)函数
        AudioQueueStart(queue, nil);
    }

    - (UInt32)readPacketsIntoBuffer:(AudioQueueBufferRef)buffer {

        UInt32      numBytes, numPackets;

        // 从文件中接受包数据并保存到缓存(buffer)中
        numPackets = numPacketsToRead;

        AudioFileReadPackets(audioFile, NO, &numBytes, packetDescs,
                           packetIndex, &numPackets, buffer->mAudioData);

        if (numPackets > 0) {
            buffer->mAudioDataByteSize = numBytes;
            AudioQueueEnqueueBuffer(queue, buffer,
                  (packetDescs ? numPackets : 0), packetDescs);
            packetIndex += numPackets;
        }
        return numPackets;
    }
    @end


        
    最新技术文章:
    ▪Android开发之登录验证实例教程
    ▪Android开发之注册登录方法示例
    ▪Android获取手机SIM卡运营商信息的方法
    ▪Android实现将已发送的短信写入短信数据库的...
    ▪Android发送短信功能代码
    ▪Android根据电话号码获得联系人头像实例代码
    ▪Android中GPS定位的用法实例
    ▪Android实现退出时关闭所有Activity的方法
    ▪Android实现文件的分割和组装
    ▪Android录音应用实例教程
    互联网 iis7站长之家
    ▪Android实现侦听电池状态显示、电量及充电动...
    ▪Android获取当前已连接的wifi信号强度的方法
    ▪Android实现动态显示或隐藏密码输入框的内容
    ▪根据USER-AGENT判断手机类型并跳转到相应的app...
    ▪Android Touch事件分发过程详解
    ▪Android中实现为TextView添加多个可点击的文本
    ▪Android程序设计之AIDL实例详解
    ▪Android显式启动与隐式启动Activity的区别介绍
    ▪Android按钮单击事件的四种常用写法总结
    ▪Android消息处理机制Looper和Handler详解
    ▪Android实现Back功能代码片段总结
    ▪Android实用的代码片段 常用代码总结
    ▪Android实现弹出键盘的方法
    ▪Android中通过view方式获取当前Activity的屏幕截...
    ▪Android提高之自定义Menu(TabMenu)实现方法
    ▪Android提高之多方向抽屉实现方法
    ▪Android提高之MediaPlayer播放网络音频的实现方法...
    ▪Android提高之MediaPlayer播放网络视频的实现方法...
    ▪Android提高之手游转电视游戏的模拟操控
     


    站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3