Seguindo o artigo anterior, iremos agora utilizar o Flex em conjunto com o PHP para salvar as imagens no servidor. A conexão entre o Flex e o PHP será realizada pelo AMFPHP.
Este artigo teve uma grande ajuda do Bruno Santana, que nos mandou o código sobre a gravação do arquivo pela webcam.
Pré requisitos
- Wamp Server instalado
- Biblioteca AMFPHP – http://www.amfphp.org/
Passos iniciais
- Cria a pasta c:wampwwwFlexFoto
- Crie o projeto FlexFoto. Atenção na parte de definição do Output Folder:
e
- Copie a pasta amfphp do zip para c:wampwwwFlexFoto
- O esquema de pastas fica como na figura a seguir:
Agora vamos configurar o services-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<services-config>
<services>
<service id="amf-service"
class="flex.messaging.services.RemotingService"
messageTypes="flex.messaging.messages.RemotingMessage">
<destination id="amf">
<channels>
<channel ref="amf-endpoint"/>
</channels>
<properties>
<source>*</source>
</properties>
</destination>
</service>
</services>
<channels>
<channel-definition id="amf-endpoint"
class="mx.messaging.channels.AMFChannel">
<endpoint uri="amfphp/gateway.php"
class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
</channels>
</services-config>
E configuramos o services-config.xml nas propriedades do projeto Flex:
Agora vamos fazer um teste de conexão. Crie a seguinte classe: HelloWorld.php em www/FlexFoto/amfphp/services
<?php
class HelloWorld
{
function Say()
{
return "Hello World from amfphp";
}
}
E no Flex, adicione o seguinte código:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="955" minHeight="600">
<fx:Declarations>
<s:RemoteObject id="HelloWorld"
destination="amf" source="HelloWorld">
<s:method name="Say" result="OnSayResult(event)"/>
</s:RemoteObject>
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
protected function OnSayResult(e:ResultEvent):void
{
mx.controls.Alert.show(e.result.toString());
}
]]>
</fx:Script>
<s:Button label="Hello World">
<s:click>
<![CDATA[
HelloWorld.Say();
]]>
</s:click>
</s:Button>
</s:Application>
Teste a aplicação. Veja inicialmente se a aplicação abre com o endereço "localhost" e não "c:….". Clique no botão e verifique se a mensagem "Hello World from AMFPHP" surgir. Se for algum erro, você precisa investigar o erro através da mensagem de erro padrão do log de erros do wamp (c:wamplogsapache_error.php). Se não achou nada, use o Firefox+Firebug+Flashbug ou então use o Charles Proxy(http://www.charlesproxy.com/)
Configurando a WebCam
Esta parte é tranquila, já que vimos isso no artigo anterior. Apague o “hello world” do teste de conexão e faça:
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"> <fx:Declarations> <s:RemoteObject id="Foto" destination="amf" source="Foto"> </s:RemoteObject> </fx:Declarations> <mx:VideoDisplay id="webcam" width="160" height="120" top="100" left="100" > <mx:creationComplete> <![CDATA[ webcam.attachCamera(Camera.getCamera()); ]]> </mx:creationComplete> </mx:VideoDisplay> <s:Button label="Salvar!!" top="50" left="150"> </s:Button> </s:Application>
Salvando a imagem no servidor
Até aqui apenas exibimos a câmera e o botão salvar. Vamos agora dar a funcionalidade necessária para enviar a imagem da WebCam para o servidor. Crie o arquivo Foto.php na pasta services, com o seguinte conteúdo:
<?php
class Foto
{
function __construct()
{
}
function Save($fotoAsString)
{
//obtém um id unico para o arquivo
$nomeArquivo = uniqid();
//configura o nome do arquivo
$nomeImagem = "imagem/{$nomeArquivo}.jpg";
//abre o arquivo. A opção w vai criá-lo, caso nao exista
$arquivo = fopen($nomeImagem, 'w');
//escreve no arquivo
fwrite($arquivo, base64_decode($fotoAsString));
return "ok";
}
}
Aqui, criamos no método Save uma rotina para salvar a imagem no disco. Isso é feito graças a transformação da foto em string e na sua volta, pelo método base64_decode.
Exibindo as imagens gravadas no Flex
Assim que a foto é gravada, a reqisição feita pelo Flex volta, com um "ok". Então podemos usar outra rotina para ler todas as imagens e apresentá-las no flex:
<s:List
id="exibirImagens"
top="10"
left="150"
right="10"
bottom="10"
width="530"
height="400"
>
<s:layout>
<s:TileLayout
requestedColumnCount="5"
requestedRowCount="8"
horizontalGap="2"
verticalGap="2"/>
</s:layout>
<s:itemRenderer>
<fx:Component>
<mx:Image source="{data}" />
</fx:Component>
</s:itemRenderer>
</s:List>
No código acima, criamos uma lista do tipo tile, cujo o itemrenderer é um componente do tipo image.
Para preencher esta lista, usamos o seguinte código:
protected function OnGetAll(event:ResultEvent):void
{
exibirImagens.dataProvider = new ArrayList((event.result as Array));
}
Ou seja, sempre que chamamos o método GetAll, o php se encarrega de obter uma lista de imagens e retorná-la para o Flex. Com esta lista preenchemos o dataProvider da lista de imagens que possui o itemRenderer.
Para finalizar, o codigo php do método GetAll():
function GetAll()
{
//http://snipplr.com/view/742/read-images-of-directory/
$folder = opendir("imagem");
$pic_types = array("jpg");
$index = array();
while ($file = readdir ($folder)) {
if(in_array(substr(strtolower($file), strrpos($file,".") + 1),$pic_types))
{
array_push($index,"amfphp/services/imagem/$file");
}
}
closedir($folder);
return $index;
}
O código php lê o diretório e retorna uma array com o caminho completo da imagem.
O resultado final é visto na tela abaixo:




