首页 > 语言 > 关键词  > php教程最新资讯  > 正文

使用 PHP 5.0创建图形的巧妙方法

2008-09-08 08:37 · 稿源:互联网
本文将展示如何使用PHP构建面向对象的图形层。使用面向对象的系统可以用来构建复杂的图形,这比使用标准PHP库中所提供的基本功能来构建图形简单很多。

我将图形编辑程序分为两类:一类是绘图程序,利用这种程序可以一个像素一个像素地绘制图像;另外一类是制图程序,这种程序提供了一组对象,例如线、椭圆和矩形,您可以使用这些对象来组合成一幅大图像,例如JPEG。绘图程序非常适合进行像素级的控制。但是对于业务图形来说,制图程序是比较好的方式,因为大部分图形都是由矩形、线和椭圆组成的。

PHP内置的制图基本操作与绘图程序非常类似。它们对于绘制图像来说功能非常强大;但是如果您希望自己的图像是一组对象集合时,这就不太适合了。本文将向您展示如何在PHP图形库的基础上构建一个面向对象的图形库。您将使用PHPV5中提供的面向对象的扩展。

具有面向对象的图形支持之后,您的图形代码就非常容易理解和维护了。您可能还需要从一种单一的图形源将图形合成为多种类型的媒介:Flash电影、SVG等等。

目标

创建一个图形对象库包括3个主要的目标:

从基本操作切换到对象上

它不使用imageline、imagefilledrectangle以及其他图形函数,这个库应该提供一些对象,例如Line、Rectangle和Oval,它们可以用来制作图像。它应该还可以支持构建更大的复杂对象或对对象进行分组的功能。

可以进行z值排序

制图程序让画家可以在画面表面上上下移动图形对象。这个库应该可以支持将一个对象放到其他对象前后的功能:它使用了一个z值,用来定义对象从制图平面开始的高度。z值越大的对象被画得越晚,也就出现在那些z值较小的对象之上。

提供viewport的转换

通常,数据的坐标空间与图像的坐标空间是不同的。PHP中的图形基本操作是对图像的坐标平面进行操作的。这个图形库应该支持viewport的规范,这样您就可以在一个程序员熟悉的坐标系统中指定图形了,并且可以自动进行伸缩来适应任何图像的大小。

由于这里有很多特性,您将一步步地编写代码来展示这些代码如何不断增加功能。

基础知识

让我们首先来看一个图形环境对象和一个名为GraphicsObject的接口,它是使用一个Line类实现的,功能就是用来画线。UML如图1所示。

图1.图形环境和图形对象接口


GraphicsEnvironment类中保存了图形对象和一组颜色,还包括宽度和高度。saveAsPng方法负责将当前的图像输出到指定的文件中。

GraphicsObject是任何图形对象都必须使用的接口。要开始使用这个接口,您所需要做的就是使用render方法来画这个对象。它是由一个Line类实现的,它利用4个坐标:开始和结束的x值,开始和结束的y值。它还有一个颜色。当调用render时,这个对象从sx,sy到ex,ey画一条由名字指定的颜色的线。

这个库的代码如清单1所示。

清单1.基本的图形库

<?phpclassGraphicsEnvironment{public$width;public$height;public$gdo;public$colors=array();publicfunction__construct($width,$height){$this->width=$width;$this->height=$height;$this->gdo=imagecreatetruecolor($width,$height);$this->addColor("white",255,255,255);imagefilledrectangle($this->gdo,0,0,$width,$height,$this->getColor("white"));}publicfunctionwidth(){return$this->width;}publicfunctionheight(){return$this->height;}publicfunctionaddColor($name,$r,$g,$b){$this->colors[$name]=imagecolorallocate($this->gdo,$r,$g,$b);}publicfunctiongetGraphicObject(){return$this->gdo;}publicfunctiongetColor($name){return$this->colors[$name];}publicfunctionsaveAsPng($filename){imagepng($this->gdo,$filename);}}abstractclassGraphicsObject{abstractpublicfunctionrender($ge);}classLineextendsGraphicsObject{private$color;private$sx;private$sy;private$ex;private$ey;publicfunction__construct($color,$sx,$sy,$ex,$ey){$this->color=$color;$this->sx=$sx;$this->sy=$sy;$this->ex=$ex;$this->ey=$ey;}publicfunctionrender($ge){imageline($ge->getGraphicObject(),$this->sx,$this->sy,$this->ex,$this->ey,$ge->getColor($this->color));}}?>

测试代码如清单2所示:

清单2.基本图形库的测试代码

<?phprequire_once("glib.php");$ge=newGraphicsEnvironment(400,400);$ge->addColor("black",0,0,0);$ge->addColor("red",255,0,0);$ge->addColor("green",0,255,0);$ge->addColor("blue",0,0,255);$gobjs=array();$gobjs[]=newLine("black",10,5,100,200);$gobjs[]=newLine("blue",200,150,390,380);$gobjs[]=newLine("red",60,40,10,300);$gobjs[]=newLine("green",5,390,390,10);foreach($gobjsas$gobj){$gobj->render($ge);}$ge->saveAsPng("test.png");?>

这个测试程序创建了一个图形环境。然后创建几条线,它们指向不同的方向,具有不同的颜色。然后,render方法可以将它们画到图形平面上。最后,这段代码将这个图像保存为test.png。

在本文中,都是使用下面的命令行解释程序来运行这段代码,如下所示:

%phptest.php%


图2显示了所生成的test.png文件在Firefox中的样子。

图2.简单的图形对象测试



这当然不如蒙娜丽莎漂亮,但是可以满足目前的工作需要。

#p#分页标题#e#

添加维数

我们的第一个需求——提供图形对象的能力——已经满足了,现在应该开始满足第二个需求了:可以使用一个z值将一个对象放到其他对象的上面或下面。

我们可以将每个z值当作是原始图像的一个面。所画的元素是按照z值从最小到最大的顺序来画的。例如,让我们画两个图形元素:一个红色的圆和一个黑色的方框。圆的z值是100,而黑方框的z值是200。这样会将圆放到方框之后,如图3所示:

图3.不同z值的面



我们只需要修改一下z值就可以将这个红圆放到黑方框之上。要实现这种功能,我们需要让每个GraphicsObject都具有一个z()方法,它返回一个数字,就是z值。由于您需要创建不同的图形对象(Line、Oval和Rectangle),您还需要创建一个基本的类BoxObject,其他3个类都使用它来维护起点和终点的坐标、z值和这个对象的颜色(请参看图4)。

图4.给系统添加另外一维:z值


这个图形库的新代码如清单3所示:

清单3.可以处理z信息的图形库

<?phpclassGraphicsEnvironment{public$width;public$height;public$gdo;public$colors=array();publicfunction__construct($width,$height){$this->width=$width;$this->height=$height;$this->gdo=imagecreatetruecolor($width,$height);$this->addColor("white",255,255,255);imagefilledrectangle($this->gdo,0,0,$width,$height,$this->getColor("white"));}publicfunctionwidth(){return$this->width;}publicfunctionheight(){return$this->height;}publicfunctionaddColor($name,$r,$g,$b){$this->colors[$name]=imagecolorallocate($this->gdo,$r,$g,$b);}publicfunctiongetGraphicObject(){return$this->gdo;}publicfunctiongetColor($name){return$this->colors[$name];}publicfunctionsaveAsPng($filename){imagepng($this->gdo,$filename);}}abstractclassGraphicsObject{abstractpublicfunctionrender($ge);abstractpublicfunctionz();}abstractclassBoxObjectextendsGraphicsObject{protected$color;protected$sx;protected$sy;protected$ex;protected$ey;protected$z;publicfunction__construct($z,$color,$sx,$sy,$ex,$ey){$this->z=$z;$this->color=$color;$this->sx=$sx;$this->sy=$sy;$this->ex=$ex;$this->ey=$ey;}publicfunctionz(){return$this->z;}}classLineextendsBoxObject{publicfunctionrender($ge){imageline($ge->getGraphicObject(),$this->sx,$this->sy,$this->ex,$this->ey,$ge->getColor($this->color));}}classRectangleextendsBoxObject{publicfunctionrender($ge){imagefilledrectangle($ge->getGraphicObject(),$this->sx,$this->sy,$this->ex,$this->ey,$ge->getColor($this->color));}}classOvalextendsBoxObject{publicfunctionrender($ge){$w=$this->ex-$this->sx;$h=$this->ey-$this->sy;imagefilledellipse($ge->getGraphicObject(),$this->sx+($w/2),$this->sy+($h/2),$w,$h,$ge->getColor($this->color));}}?>

测试代码也需要进行更新,如清单4所示。

清单4.更新后的测试代码

<?phprequire_once("glib.php");functionzsort($a,$b){if($a->z()<$b->z())return-1;if($a->z()>$b->z())return1;return0;}$ge=newGraphicsEnvironment(400,400);$ge->addColor("black",0,0,0);$ge->addColor("red",255,0,0);$ge->addColor("green",0,255,0);$ge->addColor("blue",0,0,255);$gobjs=array();$gobjs[]=newOval(100,"red",50,50,150,150);$gobjs[]=newRectangle(200,"black",100,100,300,300);usort($gobjs,"zsort");foreach($gobjsas$gobj){$gobj->render($ge);}$ge->saveAsPng("test.png");?>

此处需要注意两件事情。首先是我们添加了创建Oval和Rectangle对象的过程,其中第一个参数是z值。其次是调用了usort,它使用了zsort函数来对图形对象根据z值进行排序。

在运行这个程序时,test.png文件应该如图5所示。

图5.红圆在黑方框之后



现在修改下面的代码:

$gobjs[]=newOval(200,"red",50,50,150,150);$gobjs[]=newRectangle(100,"black",100,100,300,300);

再次运行这个代码,突然这个椭圆就在这个方框上面了,如图6所示。

图6.红圆现在在黑方框上面了



红圆现在就出现在黑方框上面了,尽管它是先创建的,也是首先添加到数组中的。这就是z值的实际价值:您可以按照任何顺序来创建对象,并可以通过调整每个对象的z值来调整彼此之间的相对位置。

在这段代码中,z值排序是在这个库之外实现的。让我们通过创建一个新容器对象Group来实现这种功能,其中保存了一组GraphicsObject对象。Group对象然后再处理排序的问题。

Group类的代码如清单5所示。

清单5.Group类

functionzsort($a,$b){if($a->z()<$b->z())return-1;if($a->z()>$b->z())return1;return0;}classGroupextendsGraphicsObject{private$z;protected$members=array();publicfunction__construct($z){$this->z=$z;}publicfunctionadd($member){$this->members[]=$member;}publicfunctionrender($ge){usort($this->members,"zsort");foreach($this->membersas$gobj){$gobj->render($ge);}}publicfunctionz(){return$this->z;}}

Group对象的任务是保持一个对象数组,然后在画图时,逐个对对象zo进行排序和画图。

更新后的测试代码如清单6所示。

清单6.更新后的测试代码

<?phprequire_once("glib.php");$ge=newGraphicsEnvironment(400,400);$ge->addColor("black",0,0,0);$ge->addColor("red",255,0,0);$ge->addColor("green",0,255,0);$ge->addColor("blue",0,0,255);$g1=newGroup(0);$g1->add(newOval(200,"red",50,50,150,150));$g1->add(newRectangle(100,"black",100,100,300,300));$g1->render($ge);$ge->saveAsPng("test.png");?>


现在所有的客户机需要做的是创建一个Group对象。它会处理排序和其他操作。

#p#分页标题#e#

创建viewport

viewport是一个人造的坐标系统,可以转换成图像的物理坐标系统。viewport的扩展可以是您希望的任何东西。例如,x和y轴的起点和终点可以是-2和2,这样viewport坐标平面的中心就是0,0。这对于三角图形(例如sin和cosine)来说是很好的一个viewport。或者,这个viewport也可以是不对称的,其中y值的范围从-1到1,x值的范围是从0到10,000,这取决于您的需要。

这个viewport的其他值可以确保构建一个400X400的图像所采用的逻辑与构建一个4000X2000的图像所采用的逻辑是相同的。代码负责向这个viewport中写入数据,然后这个viewport自动实现到图像的物理尺寸的自动映射。

要让您的viewport正常工作,您需要将这个viewport的范围从0,0修改为1,1,这可以让图形对象回调图形环境,从而将viewport的坐标转换成物理坐标。您可以将所有的代码都放到BoxObject基类中进行简化。

图7显示了有关新添加的代码的两个内容。首先是添加的tx和ty方法,这会将x和y坐标从viewport转换成物理图像的坐标。第二个是对BoxObject增加了draw方法,它的派生类应该用来进行制图。BoxObject在render方法中实现viewport的转换,并使用物理坐标来调用draw方法。使用这种方法,Line、Oval和Rectangle类都可以利用viewport坐标,而不需要担心坐标转换的问题。

图7.所添加的图形环境viewport转换


这个新库的代码如清单7所示:

清单7.具有viewport支持的图形库

<?phpclassGraphicsEnvironment{public$width;public$height;public$gdo;public$colors=array();publicfunction__construct($width,$height){$this->width=$width;$this->height=$height;$this->gdo=imagecreatetruecolor($width,$height);$this->addColor("white",255,255,255);imagefilledrectangle($this->gdo,0,0,$width,$height,$this->getColor("white"));}publicfunctionwidth(){return$this->width;}publicfunctionheight(){return$this->height;}publicfunctionaddColor($name,$r,$g,$b){$this->colors[$name]=imagecolorallocate($this->gdo,$r,$g,$b);}publicfunctiongetGraphicObject(){return$this->gdo;}publicfunctiongetColor($name){return$this->colors[$name];}publicfunctionsaveAsPng($filename){imagepng($this->gdo,$filename);}publicfunctiontx($x){return$x*$this->width;}publicfunctionty($y){return$y*$this->height;}}abstractclassGraphicsObject{abstractpublicfunctionrender($ge);abstractpublicfunctionz();}functionzsort($a,$b){if($a->z()<$b->z())return-1;if($a->z()>$b->z())return1;return0;}classGroupextendsGraphicsObject{private$z;protected$members=array();publicfunction__construct($z){$this->z=$z;}publicfunctionadd($member){$this->members[]=$member;}publicfunctionrender($ge){usort($this->members,"zsort");foreach($this->membersas$gobj){$gobj->render($ge);}}publicfunctionz(){return$this->z;}}abstractclassBoxObjectextendsGraphicsObject{protected$color;protected$sx;protected$sy;protected$ex;protected$ey;protected$z;publicfunction__construct($z,$color,$sx,$sy,$ex,$ey){$this->z=$z;$this->color=$color;$this->sx=$sx;$this->sy=$sy;$this->ex=$ex;$this->ey=$ey;}publicfunctionrender($ge){$rsx=$ge->tx($this->sx);$rsy=$ge->ty($this->sy);$rex=$ge->tx($this->ex);$rey=$ge->ty($this->ey);$this->draw($rsx,$rsy,$rex,$rey,$ge->getGraphicObject(),$ge->getColor($this->color));}abstractpublicfunctiondraw($sx,$sy,$ex,$ey,$gobj,$color);publicfunctionz(){return$this->z;}}classLineextendsBoxObject{publicfunctiondraw($sx,$sy,$ex,$ey,$gobj,$color){imageline($gobj,$sx,$sy,$ex,$ey,$color);}}classRectangleextendsBoxObject{publicfunctiondraw($sx,$sy,$ex,$ey,$gobj,$color){imagefilledrectangle($gobj,$sx,$sy,$ex,$ey,$color);}}classOvalextendsBoxObject{publicfunctiondraw($sx,$sy,$ex,$ey,$gobj,$color){$w=$ex-$sx;$h=$ey-$sy;imagefilledellipse($gobj,$sx+($w/2),$sy+($h/2),$w,$h,$color);}}?>

GraphicsEnvironment类中的viewport转换代码是高亮显示的,正如GraphicsObject中的render代码一样,这会回调图形环境来进行坐标转换的工作。

测试代码只需要稍加修改即可(请参看清单8)。这些对象现在需要在0,0和1,1之间的viewport中进行指定。

清单8.使用新viewport坐标的测试代码

$g1=newGroup(0);$g1->add(newOval(200,"red",0.1,0.1,0.5,0.5));$g1->add(newRectangle(100,"black",0.4,0.4,0.9,0.9));


这非常不错,但是您可能实际上并不希望使用一个0,0与1,1之间的viewport;而是希望使用任意的viewport——例如,在-1000,-1000到1000,1000之间。要让这成为可能,这个图形环境就需要知道viewport的起点和终点。

#p#分页标题#e#

图8显示了更新后的GraphicsEnvironment类,它具有几个成员变量,用来存储viewport的起点和终点坐标:vsx,vsy和vex,vey。图形对象并不需要进行修改。

图8.具有灵活viewport规范的图形环境



清单9显示了更新后的GraphicsEnvironment代码。

清单9.更新后的GraphicsEnvironment代码

classGraphicsEnvironment{public$vsx;public$vsy;public$vex;public$vey;public$width;public$height;public$gdo;public$colors=array();publicfunction__construct($width,$height,$vsx,$vsy,$vex,$vey){$this->vsx=$vsx;$this->vsy=$vsy;$this->vex=$vex;$this->vey=$vey;$this->width=$width;$this->height=$height;$this->gdo=imagecreatetruecolor($width,$height);$this->addColor("white",255,255,255);imagefilledrectangle($this->gdo,0,0,$width,$height,$this->getColor("white"));}publicfunctionwidth(){return$this->width;}publicfunctionheight(){return$this->height;}publicfunctionaddColor($name,$r,$g,$b){$this->colors[$name]=imagecolorallocate($this->gdo,$r,$g,$b);}publicfunctiongetGraphicObject(){return$this->gdo;}publicfunctiongetColor($name){return$this->colors[$name];}publicfunctionsaveAsPng($filename){imagepng($this->gdo,$filename);}publicfunctiontx($x){$r=$this->width/($this->vex-$this->vsx);return($x-$this->vsx)*$r;}publicfunctionty($y){$r=$this->height/($this->vey-$this->vsy);return($y-$this->vsy)*$r;}}

现在这个构造函数可以利用另外4个参数了,它们分别是viewport的起点和终点。tx和ty函数使用新的viewport坐标,并将viewport坐标转换成物理坐标。

测试代码如清单10所示。

清单10.viewport测试代码

<?phprequire_once("glib.php");$ge=newGraphicsEnvironment(400,400,-1000,-1000,1000,1000);$ge->addColor("black",0,0,0);$ge->addColor("red",255,0,0);$ge->addColor("green",0,255,0);$ge->addColor("blue",0,0,255);$g1=newGroup(0);$g1->add(newOval(200,"red",-800,-800,0,0));$g1->add(newRectangle(100,"black",-400,-400,900,900));$g1->render($ge);$ge->saveAsPng("test.png");?>

这段测试代码会在-1000,-1000与1000,000之间创建一个viewport。对象会被重新放置,以适合这个新的坐标系统。

测试代码的输出如图9所示。

图9.viewport绘制的图像转换为一个400X400的图像



如果您希望图像的大小是400X200,就可以采用下面的方法:

$ge=newGraphicsEnvironment(400,200,-1000,-1000,1000,1000);

您会得到一个纵向缩小后的图像,如图10所示。

图10.图形的400X200版本



这展示了代码如何自动调整图像的大小来适合所请求的图像。

结束语

动态图可以为应用程序添加一个新的交互层。使用这种面向对象的系统可以让构建复杂图形变得非常简单,比使用标准的PHP库中的基本操作来画图更加简单。另外,您还可以实现画不同大小或类型的图像,并且可以长期使用相同的代码来画不同类型的媒介,例如SVG、PDF、Flash和其他类型的媒介。

举报

  • 相关推荐
  • 曝iPhone 17 Pro要涨价:苹果扛不住了

    当地时间7月30日,美国总统特朗普发文称,自8月1日起,美国将对来自印度的商品征收25%的关税。 分析师称,若25%的关税生效,苹果的净利润将会受到重大影响,因为印度约占iPhone总出货量的20%,其中大部分销往美国,价值约400亿美元。 更严重的是,短期内苹果无处可去,只能承担关税带来的负面影响,如今要在美国大规模组装iPhone几乎不可能,而且可能需要数十年才能实�

  • iPhone 17 Pro橙色机模曝光 全系所有配色揭晓

    ​近日,知名科技博主Sonny Dickson提前晒出iPhone17系列四款机型全配色方案及核心设计细节。据披露,该系列在延续经典黑白基调的同时,首次引入多款鲜明配色:iPhone17Pro系列提供黑、白、蓝、橙四色,其中橙色以高饱和度成为最抢眼选项;iPhone17Air推出黑、白、浅金、天蓝四款清新配色;标准版iPhone17则包含黑、白、浅蓝及粉色,满足多元化审美需求。 工业设计层面,iPhone17系列�

  • 苹果iOS 26公测版升级教程来了:iPhone 11系列及之后机型都能体验

    日前,苹果正式推送了首个iOS 26公测版。 这次苹果放弃了iPhone XS、iPhone XS Max和iPhone XR三款机器,iPhone 11系列、iPhone SE二代及后续机型,均可升级。 作为公测版,目前日常使用已经趋于稳定,没有什么硬性bug,卡顿和发热、耗电情况也比之前好了很多。 而且公测版覆盖范围更大,普通用户想要体验,也能非常方便的申请资格,体验全新设计。

  • iPhone 17 Pro橙色机模上手:最鲜艳的苹果手机

    博主Majin Bu带来了iPhone 17 Pro橙色机模的上手视频。对比网络渲染图,iPhone 17 Pro橙色机模的饱和度要低。 据悉,iPhone 17 Pro提供橙色、银色、钛灰和蓝色四种配色,其中橙色是4款配色中辨识度最高、颜色最鲜艳的一款。 这次iPhone 17 Pro配备了三颗4800万像素摄像头,采用横向大矩阵DECO设计,LED闪光灯与LiDAR扫描仪位居右侧,是苹果近年来变化最大的一款。

  • iPhone 17系列4款手机壳出炉:Pro版变化最大

    有博主在社交平台上分享了iPhone 17系列第三方MagSafe保护壳,这些保护壳对应的机型分别是iPhone 17、iPhone 17 Air、iPhone 17 Pro和iPhone 17 Pro Max。 其中iPhone 17 Pro和17 Pro Max的保护壳有了明显变化,这两款机型的圆环都有一个缺口,而iPhone 17和iPhone 17 Air的MagSafe设计与前代iPhone机型没有变化。 据悉,iPhone 17 Pro系列的后置摄像头模组更大,背面的苹果Logo位置下移,新的MagSafe手机壳专门�

  • iPhone 17 Pro所有配色全部曝光:橙色最吸睛

    博主Majin Bu在社交平台上晒出了iPhone 17 Pro的镜头盖板,一共有4款配色,分别是橙色、银色、钛灰和蓝色,其中橙色的辨识度最高。 基于曝光的镜头盖板,博主还绘制了iPhone 17 Pro的四款配色渲染图,这是苹果史上变化最大的iPhone。 如图所示,iPhone 17 Pro采用横向大矩阵设计,后置三摄位置在左侧,闪光灯和LIDAR激光雷达扫描仪位于矩阵相机右侧,外观接近小米11 Ultra。

  • 折叠屏iPhone首发!苹果马上启动iOS 27开发工作

    苹果很快就会启动iOS 27的开发工作,该公司将优先为折叠屏iPhone打造专属软件功能。 按照计划,iOS 27会在明年上半年的WWDC开发者大会上正式亮相,明年9月份推出正式版系统,由折叠屏iPhone首发搭载。 尽管Mark Gurman并未爆料iOS 27会有哪些折叠屏定制功能,但考虑到折叠屏的屏幕形态和定位,iOS 27首先要做的是分屏功能,业界期待苹果利用折叠屏的大屏优势实现更高效的多任务

  • iPhone 17 Pro橙色新配色上热搜:辨识度最高的苹果手机

    微博话题iPhone 17 Pro橙色新配色”冲上热搜榜,引发热议。 据博主爆料,iPhone 17 Pro将提供橙色、银色、钛灰和蓝色四种配色,其中橙色是苹果新加入的配色,其饱和度很高,网友们对这款配色褒贬不一。

  • 友商不够看!库克:中国最畅销台式机、笔记本、手机都是苹果 iPhone包揽前三名

    今天苹果发布了财报,其中iPhone的销量在中国重新出现了增长,这让库克非常激动。 苹果首席执行官蒂姆库克(Tim Cook)在财报电话会议上表示,在中国市场,iPhone 销量实现反弹,上一季度该地区总收入增长4.35%。 库克虽然没有透露具体数字,不过在会议中表示,中国的iPhone用户数量达到历史新高,并将销量的回升的主要原因,归功于国补政策。

  • iPhone17 Pro支持8倍光学变焦 或迎相机重大升级

    近日,有爆料者透露某家电影公司正在制作iPhone17Pro的广告,同时还爆料了这款手机诸多令人瞩目的核心功能与特性。 在相机功能方面,iPhone17Pro将迎来显著升级。其中,长焦镜头升级堪称一大亮点,它支持8倍光学变焦,要知道iPhone16Pro仅支持5倍光学变焦,而且能在不同焦距下实现连续光学变焦,这无疑将为用户带来更强大的远距离拍摄能力,仿佛给手机装上了“望远镜”。