flex图像灰度化数组取值_使用Flex在Twitter上共享媒体,第二部分:图像

flex图像灰度化数组取值

In the first part of this series on sharing media on Twitter with Flex, we discussed how to create the interface for a Flex application with the beta of Flash Catalyst. Then we used the beta of Flash Builder 4 to create a Twitter application for the browser that used PHP to proxy calls to the Twitter API. In this article we’re going to enhance that Flex application by adding the ability to upload photographs to the popular Flickr image hosting service, and then integrate a shortened link to the photo into a post to Twitter.

本系列第一部分中,有关在Twitter上使用Flex共享Twitter上的媒体 ,我们讨论了如何使用Flash Catalyst Beta版为Flex应用程序创建界面。 然后,我们使用Flash Builder 4 beta版为浏览器创建一个Twitter应用程序,该应用程序使用PHP代理对Twitter API的调用。 在本文中,我们将通过添加以下功能来增强该Flex应用程序:将照片上传到流行的Flickr图像托管服务,然后将到照片的缩短链接集成到Twitter的帖子中。

When you’re done with the tutorial, test your knowledge by taking our article quiz!

学习完本教程后, 请参加我们的文章测验测试您的知识

上传过程 (The Upload Process)

Uploading a photograph and shortening its link can be done a number of ways in the application we’re building. We have to first upload the image, retrieve a link to it, and then submit that link to a URL shortening service. If we automate the whole process so that it works as soon as the user posts their tweet, we risk a long time delay; that’s because it requires three calls to different servers. Instead we’ve chosen the following process:

在我们正在构建的应用程序中,可以通过多种方式上传照片并缩短其链接。 我们必须首先上传图像,检索图像的链接,然后将该链接提交到URL缩短服务。 如果我们使整个过程自动化,以使它在用户发布其推文后立即生效,则可能会造成长时间的延迟; 那是因为它需要对不同服务器的三个调用。 相反,我们选择了以下过程:

  1. user uploads the photo

    用户上传照片
  2. link to the photo is inserted at the end of the tweet in the posting form

    在发布表单的推文末尾插入了指向照片的链接
  3. message is then sent by the user

    然后由用户发送消息

All code for this article is contained within the new file cheepcheep_image_flashbuilder.fxp, and you can download it together with all the resources from the previous article.

本文的所有代码都包含在新文件cheepcheep_image_flashbuilder.fxp ,您可以将其上一篇文章中的所有资源一起下载

浏览文件 (Browsing for Files)

The ActionScript FileReference class gives us the ability to upload and download files from a Flash application. Its browse method uses an operating system dialog box to locate a file; each instance of FileReference will refer to a single file on the user’s system. Make sure that a namespace is added for net to the Application tag:

ActionScript FileReference类使我们能够从Flash应用程序上载和下载文件。 它的browse方法使用操作系统对话框来查找文件。 FileReference每个实例将引用用户系统上的单个文件。 确保为net添加了一个名称空间到Application标签:

<s:Application ...
 xmlns:net="flash.net.*"/>

Create an instance of FileReference between the <fx:Declarations></fx:Declarations> tags already in the application:

在应用程序中已经在<fx:Declarations></fx:Declarations>标记之间创建FileReference的实例:

<net:FileReference id="fileReference" select="fileSelected(event)" complete="fileAccessed(event)" />

We’ve set function calls for its select and complete events that we’ll add later. Under the TextInput field for the tweet at the bottom of the application we’ve added a button; this enables us to browse for a file to upload and we’ll have that call the function browsePhoto, listed below:

我们已经为其selectcomplete事件设置了函数调用,我们将在以后添加。 在应用程序底部的tweet的TextInput字段下,我们添加了一个按钮; 这样一来,我们就可以浏览要上传的文件,并且我们将调用以下函数: browsePhoto

private function browsePhoto(evt:MouseEvent):void {
 var arr:Array = [];
 arr.push(new FileFilter("Images", ".gif;*.jpeg;*.jpg;*.png"));
 fileReference.browse(arr);        
}

This function creates an array and populates it with a FileFilter object to limit the file extensions the user can choose. It then calls the browse method of the FileReference instance, passing the array as an argument. This will launch an operating system dialog box that will open to the most recently browsed directory. The function for the select event will then fire once the user has selected a file. It loads the file, which in turn will fire the complete event that displays the name of the file to the user in our application. It’s in a new Label component that we added next to the browse button. You could use this function to display a preview of the image if required:

此函数创建一个数组,并使用FileFilter对象填充该数组,以限制用户可以选择的文件扩展名。 然后,它调用FileReference实例的FileReference方法,并将数组作为参数传递。 这将启动一个操作系统对话框,该对话框将打开到最近浏览的目录。 用户选择文件后,就会触发select事件的功能。 它会加载文件,这将触发将在我们的应用程序中向用户显示文件名的complete事件。 它在我们添加到浏览按钮旁边的新Label组件中。 如果需要,可以使用此功能显示图像的预览:

private function fileSelected(evt:Event):void {  fileReference.load(); }

private function fileSelected(evt:Event):void { fileReference.load(); }

private function fileAccessed(evt:Event):void {  fileName.text = "File selected: " + fileReference.name; }

私有函数fileAccessed(evt:Event):void {fileName.text =“所选文件:” + fileReference.name; }

使用Flickr进行身份验证 (Authenticating with Flickr)

There are a number of services that host photographs online for free. We’ve chosen Flickr because they have a well-documented API that already has a third-party ActionScript library. Flickr does require both application authentication and user permission before an application can use its services. The first item you’ll need is an API key for your application, which you can obtain for free; the key will also have a matching “secret” for authentication. Find out more about this here:

有许多服务可免费在线托管照片。 我们之所以选择Flickr,是因为它们有一个文档齐全的API,并且已经具有第三方ActionScript库。 Flickr确实需要应用程序身份验证和用户权限,然后应用程序才能使用其服务。 您需要的第一项是应用程序的API密钥,您可以免费获得它。 该密钥还将具有匹配的用于身份验证的“秘密”。 在这里找到更多关于此的信息:

The ActionScript 3 Flickr library can be found at: http://code.google.com/p/as3flickrlib/. The last build of the library is without a method for uploading to Flickr, in either the library or the SWC. While there’s a version of an upload method in the project’s code repository, we’ve found issues in making it work. We’ve supplied a copy of the library with the Flash Builder project that has a working upload method; so far this is the only part of the library where we’ve experienced problems. The Flickr library uses additional MD5 and network utilities from http://code.google.com/p/as3corelib/ that you’ll also need to download, and we’ve included the SWC in the Flash Builder project.

可以在以下位置找到ActionScript 3 Flickr库: http : //code.google.com/p/as3flickrlib/ 。 该库的最新版本没有在库或SWC中上载到Flickr的方法。 虽然项目的代码存储库中有一个上载方法的版本,但我们发现在使它起作用时存在问题。 我们为Flash Builder项目提供了该库的副本,该副本具有有效的上载方法。 到目前为止,这是我们遇到问题的库中唯一的部分。 Flickr库使用了http://code.google.com/p/as3corelib/中的其他MD5和网络实用程序,您也需要下载它们,并且SWC已包含在Flash Builder项目中。

The Flickr process of user authentication does involve a few steps programmatically, but it should be simple enough. Ultimately you need to generate a token on Flickr for each individual user of your application, and store that token on the user’s computer for each call to Flickr. This token is a secure representation of the user’s credentials; we can use it to perform tasks like our upload without having to know these credentials. The token is generated when the user grants permission to your application on Flickr.

Flickr的用户身份验证过程确实以编程方式涉及几个步骤,但它应该足够简单。 最终,您需要在Flickr上为应用程序的每个用户生成一个令牌,并针对每次对Flickr的调用将该令牌存储在用户的计算机上。 该令牌是用户凭据的安全表示; 我们可以使用它来执行诸如上载之类的任务,而无需了解这些凭据。 当用户在Flickr上授予对您的应用程序的权限时,将生成令牌。

We’re going to use the ActionScript SharedObject to store the authorization token locally, then test to see if it exists when we browse for a file. We’ll ask the user to authenticate the application if it doesn’t exist, and write the token and user account ID when it’s retrieved. Check the code below and you’ll see that we’re importing the necessary classes from the Flickr library, creating an instance of SharedObject and the variables to hold the multiple values we’ll use during the authentication process:

我们将使用ActionScript SharedObject在本地存储授权令牌,然后在浏览文件时进行测试以查看其是否存在。 如果应用程序不存在,我们将要求用户进行身份验证,并在检索到应用程序时写入令牌和用户帐户ID。 检查下面的代码,您将看到我们正在从Flickr库中导入必要的类,创建一个SharedObject的实例,并创建变量以保存在身份验证过程中将使用的多个值:

import com.adobe.webapis.flickr.events.FlickrResultEvent;
import com.adobe.webapis.flickr.FlickrService;  
import com.adobe.webapis.flickr.methodgroups.Auth;  
import com.adobe.webapis.flickr.methodgroups.Upload;  
private var appSO:SharedObject;  
private var flickr:FlickrService;  
private var flickrApiKey:String = "yourFlickrApiKey";  
private var flickrSecret:String = "yourFlickrApiKeySecret";  
private var flickrFrob:String = "";  
private var flickrAuthToken:String = "";  
private var flickrNsid:String = "";  
private var authorizationURL:String = "";

In the getFlickrLoginCredentials function below we’re attempting to read the SharedObject for our application, creating it if it fails to exist. We’re then testing to see if the Flickr authorization token has been stored. If it’s not there we create an instance of the FlickrService, initializing it with the API key, adding the secret, assigning a handler, and calling a getFrob method. This calls Flickr to retrieve a “frob” that’s needed to fetch the authorization token — after the user has connected to Flickr and granted access permission to our application:

在下面的getFlickrLoginCredentials函数中,我们尝试为应用程序读取SharedObject ,如果它不存在,则创建它。 然后,我们正在测试以查看Flickr授权令牌是否已存储。 如果不存在,我们将创建FlickrService的实例,使用API​​密钥对其进行初始化,添加密钥,分配处理程序并调用getFrob方法。 在用户连接到Flickr并授予对我们应用程序的访问权限之后,这将调用Flickr检索获取授权令牌所需的“ frob”:

public function getFlickrLoginCredentials():void {
 appSO = SharedObject.getLocal("TestFlickrTwitter");  
 if ( appSO.data.flickrAuthToken == null ) {  
   flickr = new FlickrService(flickrApiKey);  
   flickr.secret = flickrSecret;  
   flickr.addEventListener( FlickrResultEvent.AUTH_GET_FROB, onGetFrob );  
   flickr.auth.getFrob();  
 } else {  
   flickrAuthToken = appSO.data.flickrAuthToken;  
   flickrNsid = appSO.data.flickrNsid;  
   browsePhoto();  
 }  
}

The other half of the getFlickrLoginCredentials function is an else clause; it reads the Flickr authorization token and Flickr user id from the SharedObject, and calls the browsePhoto method we described before. We’ve changed the browse for photo button to now call getFlickrLoginCredentials instead, so that we’ll put the user through the authentication process if they try to upload a photograph.

getFlickrLoginCredentials函数的另一半是else子句; 它从SharedObject读取Flickr授权令牌和Flickr用户ID,并调用我们之前介绍的browsePhoto方法。 我们将“浏览照片”按钮更改为现在改为调用getFlickrLoginCredentials ,这样,如果用户尝试上传照片,我们getFlickrLoginCredentials他们通过身份验证过程。

Below is the onGetFrob function, the result handler called when we receive a result from the getFrob call in the function above. This stores the “frob” as a local variable and creates the authorization URL that will be needed later:

下面是onGetFrob函数,当我们从上面函数中的getFrob调用接收到结果时,将调用结果处理程序。 这会将“ frob”存储为本地变量,并创建稍后将需要的授权URL:

private function onGetFrob( evt:FlickrResultEvent ):void {
 flickrFrob = evt.data.frob;  
 authorizationURL = flickr.getLoginURL(flickrFrob, "write");  
 currentState = "flickrAuthorise";  
}

The function above calls an additional state that we created for our application called flickrAuthorise. We’ll use this to display a new component that we built in Flash Catalyst; this component is a popup that contains a message to the user explaining that they need to connect to Flickr to authorize the application. The component also contains two buttons: the first to open a new browser window and connect to the Flickr authorization page, and the second to fetch the authorization token from Flickr.

上面的函数调用了我们为应用程序创建的附加状态flickrAuthorise 。 我们将使用它来显示我们在Flash Catalyst中构建的新组件。 该组件是一个弹出窗口,其中包含一条向用户发送消息,说明他们需要连接至Flickr才能授权该应用程序。 该组件还包含两个按钮:第一个按钮打开新的浏览器窗口并连接到Flickr授权页面,第二个按钮从Flickr获取授权令牌。

You’ll notice the new state listed in the application:

您会注意到应用程序中列出的新状态:

<s:states>
 <s:State name="twitterLogin"/>  
 <s:State name="twitterDisplay"/>  
 <s:State name="flickrAuthorise"/>  
</s:states>

Have a look at the visual objects in the application and you’ll see various attributes used to control them in several states. Take the browsePhotoBtn, for example; it uses the includeIn attribute to nominate which states it will appear in. An additional attribute to change the button’s alpha for the flickrAuthorise state has also been set so that this will dim when the authorization popup appears. Most of the other visual objects have the same attribute for the same effect:

看一下应用程序中的可视对象,您将看到用于在几种状态下控制它们的各种属性。 以browsePhotoBtn为例; 它使用includeIn属性指定它将出现在哪个状态。还设置了另一个属性,用于更改flickrAuthorise状态的按钮的Alpha,以便在出现授权弹出窗口时该按钮将变暗。 其他大多数视觉对象具有相同的属性以达到相同的效果:

<s:Button x="180" y="670" label="Browse for Photo" click="getFlickrLoginCredentials()" id="browsePhotoBtn" includeIn="flickrAuthorise,twitterDisplay" alpha.flickrAuthorise="0.4"/>

Clicking on the first button in our authorization component, CustomComponent2, calls a function in the main application, authoriseFlickr. This launches a new browser window calling the authorization URL created inside the onGetFrob function. It also enables the second button in the authorization component:

单击我们的授权组件CustomComponent2的第一个按钮,将在主应用程序authoriseFlickr调用一个函数。 这将启动一个新的浏览器窗口,该窗口调用在onGetFrob函数内部创建的授权URL。 它还启用了授权组件中的第二个按钮:

public function authoriseFlickr():void {
 var urlRequest:URLRequest = new URLRequest(authorizationURL);  
 navigateToURL(urlRequest, "_blank");  
 customcomponent21.button3.enabled = true;  
}

The user then has to go through a couple of steps on the Flickr site to authorize the application. The last screen they’ll see will tell them that they can close the browser window; they then should click on the second button on the authorization component, which calls the onGetTockenClick function in the main application. This in turn calls the getToken method of FlickrService. A handler function, onGetToken is specified in the onGetTockenClick function. onGetToken will receive an object from Flickr containing the authorization token and some details about the user; we use that function to store both the token and user id locally, as well as in the SharedObject. We also switch back to the main twitterDisplay state:

然后,用户必须在Flickr站点上经历几个步骤才能授权该应用程序。 他们将看到的最后一个屏幕将告诉他们可以关闭浏览器窗口。 然后,他们应该单击授权组件上的第二个按钮,该组件将在主应用程序中调用onGetTockenClick函数。 这反过来又调用getToken的方法FlickrService 。 处理程序函数onGetTokenonGetTockenClick函数中指定。 onGetToken将从Flickr接收一个对象,其中包含授权令牌和有关用户的一些详细信息; 我们使用该函数将令牌和用户ID都存储在本地以及SharedObject 。 我们还切换回主要的twitterDisplay状态:

public function onGetTokenClick():void {
 flickr.addEventListener(FlickrResultEvent.AUTH_GET_TOKEN, onGetToken);  
 flickr.auth.getToken(flickrFrob);          
}  
private function onGetToken(evt:FlickrResultEvent):void {  
 flickrAuthToken = evt.data.auth.token;  
 flickrNsid = evt.data.auth.user.nsid;  
 appSO.data.flickrAuthToken = flickrAuthToken;  
 appSO.data.flickrNsid = flickrNsid;  
 appSO.flush();  
 currentState = "twitterDisplay";  
}

This will occur the first time a user attempts to browse for a photograph, so they’ll need to browse again after authentication as this step was interrupted by this process. Once we’ve located our photo we need to upload it so that we can include a link to it in our tweet.

这将在用户第一次尝试浏览照片时发生,因此在身份验证之后,他们将需要再次浏览,因为此步骤已被该过程中断。 找到照片后,我们需要上传照片,以便可以在其推文中包含指向该照片的链接。

上传照片 (Uploading the Photo)

The adjusted upload class in the Flickr library ensures that the necessary authentication, upload process, and upload complete event are all taken care of. We’ve added a button at the bottom of the application below the Twitter post form to upload an image, and created a function for this button called uploadFlickr. This function creates a listener for the upload complete event and creates another instance of the FlickrService class, adding credentials to it. This is then used as the argument for an instance of the upload class that’s used to upload our fileReference, which was created when we browsed for a file. We’ve also added a call to the setBusyCursor method of the CursorManager to provide a simple form of feedback to the user while the upload progresses – as FlickrService is without this feature:

Flickr库中调整后的上载类可确保完成所有必要的身份验证,上载过程和上载完成事件。 我们在Twitter帖子表单下方的应用程序底部添加了一个按钮,用于上传图片,并为此按钮创建了一个函数uploadFlickr 。 此函数为上载完成事件创建一个侦听器,并创建FlickrService类的另一个实例,并向其添加凭据。 然后,将其用作用于上载我们的fileReference的上载类的实例的参数,该文件是我们在浏览文件时创建的。 我们还添加了对CursorManagersetBusyCursor方法的调用,以在上载过程中向用户提供一种简单的反馈形式-因为FlickrService没有此功能:

private function uploadFlickr():void {
 fileReference.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,uploadCompleteHandler);          
 flickr = new FlickrService(flickrApiKey);  
 flickr.secret = flickrSecret;  
 flickr.token = flickrAuthToken;  
 var uploader:Upload = new Upload(flickr);  
 uploader.upload(fileReference);  
 CursorManager.setBusyCursor();  
}

The upload will return an XML packet from Flickr containing an ID for the image uploaded, which we can utilize to construct a link to use in our tweet. With the 140-character limitation of Twitter, we need to manage this as Flickr URLs tend to be a little long. We’re going to work around this by using the URL shortening service bit.ly, which has a REST API that we can use in our application. You’ll need to create an account with bit.ly to receive an API key; this is automatically issued with the account, with your key on your account details page.

上载将从Flickr返回一个XML数据包,其中包含上载图像的ID,我们可以利用该XML数据包构建要在推文中使用的链接。 由于Twitter的字符数限制为140个字符,我们需要对此进行管理,因为Flickr URL的长度通常会有点长。 我们将通过使用URL缩短服务bit.ly来解决此问题,该服务具有一个REST API,可以在我们的应用程序中使用它。 您需要使用bit.ly创建一个帐户以接收API密钥; 这是随帐户自动发出的,您的密钥在帐户详细信息页面上。

创建指向图像的缩短链接 (Creating a Shortened Link to the Image)

The uploadCompleteHandler is specified as the result handler in uploadFlickr and will receive the XML in the data property of the event. We convert that into an XML object in the function and construct a URL combining a string, the Flickr user ID, and the photo ID. We’ve also created variables to store the bit.ly login and API key, both required for the rest call:

uploadCompleteHandler被指定为uploadCompleteHandler中的结果处理程序, uploadFlickr在事件的data属性中接收XML。 我们将其转换为函数中的XML对象,并构造一个由字符串,Flickr用户ID和照片ID组成的URL。 我们还创建了变量来存储bit.ly登录名和API密钥,其余调用都需要这些变量:

[Bindable] private var photoUrl:String = "";
private var bitlyLogin:String = "yourBitlyAccountName";  
private var bitlyApiKey:String = "yourBitlyApiKey";  
private function uploadCompleteHandler(evt:DataEvent):void {  
 CursorManager.removeBusyCursor();  
 var xData:XML = new XML(evt.data);  
 photoUrl = "http://www.flickr.com/photos/"+flickrNsid+"/"+xData.photoid;  
 bitlyService.send();  
}

The uploadCompleteHandler function calls the send method of an HTTPService once the address for the image has been constructed. Remember that the HTTPService tag needs to be nested within a <fx:Declarations> tag set. The url attribute of the HTTPService tag needs to pass a number of arguments to bit.ly, all of which are bound to application variables. We’ve set a handler for the result event of the HTTPService tag:

构造图像地址后, uploadCompleteHandler函数将调用HTTPServicesend方法。 请记住, HTTPService标记需要嵌套在<fx:Declarations>标记集中。 HTTPService标记的url属性需要将许多参数传递给bit.ly,所有这些参数都绑定到应用程序变量。 我们为HTTPService标签的result事件设置了一个处理程序:

<mx:HTTPService id="bitlyService" method="GET" url="http://api.bit.ly/shorten?version=2.0.1&amp;longUrl={photoUrl}&amp;login={bitlyLogin}&amp;apiKey={bitlyApiKey}&amp;format=xml" result="bitlyService_resultHandler(event)"/>

We allow Flash Builder to create a default handler to process the bit.ly result; the shortened URL is contained within the XML packet returned by the service, which it converted into an ActionScript object for us. The function calculates the length of the text currently in the TextInput field for the tweet and either appends the shortened URL, or truncates the text and then appends the URL:

我们允许Flash Builder创建一个默认处理程序来处理bit.ly结果; 缩短的URL包含在服务返回的XML数据包中,该数据包将其转换为ActionScript对象。 该函数计算鸣叫的TextInput字段中当前文本的长度,并附加缩短的URL,或截断文本,然后附加URL:

protected function bitlyService_resultHandler(evt:ResultEvent):void
{  
 var bitlyURL:String = evt.result.bitly.results.nodeKeyVal.shortUrl;  
 var combineTextURL:String = textinput1.text + " " + bitlyURL;  
 if ( combineTextURL.length < 140) {  
   textinput1.text = combineTextURL;  
 } else {    
   var excessChars:Number = 140 - combineTextURL.length;  
   textinput1.text = textinput1.text.substr(0,(textinput1.text.length)-Math.abs(excessChars)) + " " + bitlyURL;  
}  
}

With the image uploaded and a shortened link created for it we’re now ready to complete our tweet and post it to Twitter.

上载图像并为其创建了缩短的链接后,我们现在可以完成我们的推文并将其发布到Twitter。

Uploading directly from within a Flash application was an often-requested feature introduced with Flash Player 9. Connecting images with text is a great enhancement to Twitter, and we’re sure you’ll want to take advantage of the popularity of photo-sharing services as part of the social experience afforded by your application. The Flickr API documentation is a little intimidating to the uninitiated, especially the authentication process. Fortunately, there are ActionScript libraries available to developers that make the process easier.

直接从Flash应用程序中上传是Flash Player 9引入的一项经常需要的功能。将文本与图像连接对Twitter来说是一个很大的增强,并且我们确信您将要利用照片共享服务的普及作为您的应用程序提供的社交体验的一部分。 Flickr API文档对未使用的API有点吓人,尤其是身份验证过程。 幸运的是,开发人员可以使用ActionScript库来简化该过程。

It’s likely that there are other ways to order the application processes described in this article. Twitter is not a one-stop shop––their service is built for posting minimal text messages. We’re relying on three service calls to generate our single Twitter post; the challenge is to bring them together in a way that’s easy for the user while offering reasonable performance times.

可能还有其他方法可以订购本文中描述的应用程序过程。 Twitter并非一站式商店-其服务旨在发布最少的短信。 我们依靠三个服务电话来生成我们的单个Twitter帖子; 面临的挑战是如何以一种易于使用的方式将它们组合在一起,同时提供合理的性能时间。

Make sure you download the code for this article and give it a try.

确保下载本文的代码并尝试一下。

If you’re feeling confident, test your knowledge by taking our article quiz!

如果您有信心, 请参加我们的文章测验测试您的知识

翻译自: https://www.sitepoint.com/share-media-flex-twitter-images/

flex图像灰度化数组取值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值