Arquivo

Archive for janeiro \11\America/Fortaleza 2012

JSF 2 – PRIMEFACES – PHOTOCAM COM IMAGECROPPER

O desenvolvimento de novas versões do Primefaces, como seu próprio líder fala, está em chamas. Na última semana timemos a conclusão e lançamento da versão 3 e no mesmo dia o lançamento de novos componentes da versão 3.1.

Neste POST irei demonstrar como utilizar o componente PHOTOCAM para capturar uma imagem da sua webcam e como recortar esta imagem em seguida utilizando o IMAGECROPPER.

No nosso exemplo utilizamos:

  • Mojarra 2.1.3
  • Primefaces 3.1 SNAPSHOT
  • GlassFish 3.1.1

Let’s Rock!

Crie um novo projeto no Netbeans e dentro da pasta source crie um pacote para o managed bean, dentro da pasta web crie uma pasta para as imagens e nela uma outra pasta tmp. Veja a imagem abaixo com a estrutura básica do projeto:

Imagem 1 – Novo Projeto Netbeans

Adicione o jar do primerfaces na versão indicada acima. Na pasta web crie o arquivo index.xhtml e insira nele o código abaixo:

Codificação 1

<!--?xml version='1.0' encoding='UTF-8' ?-->



        Exemplo PhotoCam + ImageCropper











            

                Aguarde...



No arquivo index.xhtml temos o componete imagecropper definido a seguir:

Codificação 2


No atributo value definimos um objeto do tipo org.primefaces.model.CroppedImage que receberá a imagem recortada com o componente, em initialCoords definimos onde o retângulo marcador do recorte deve aparecer quando a imagem for renderizada. Além disso, temos um id para o componete, a definição se ele está ou não renderizado na view e um  outro atributo que merece um pouco mais de destaque.

No atributo image devemos especificar o caminho para a imagem capturada pela webcam, é salientar que neste atributo devemos colocar o caminho absoluto da imagem como por exemplo:

Para conseguir este caminho com precisão, coloque da forma como esta na codificação 2, pegando o caminho do contexto.

No componente photocam devemos definir um widgetVar para ser usado para chamar uma função javascript capture(), em update colocamos os ids do que deve ser atualizado ao capturar a imagem e em listenner o método a ser executado quando a captura for finalizada.

Codificação 3





Abaixo veremos a codificação do PhotoCamController:

Codificação 4

    private CroppedImage imagemRecortada;
    private String foto;
    private String fotoRecortada;
    private String arquivoFoto;
    private String arquivoFotoRecortada;
    private boolean exibeImagemCapturada;
    private ServletContext servletContext;

   /*getters e setters*/
    private String getNumeroRandomico() {
        int i = (int) (Math.random() * 10000);
        return String.valueOf(i);
    }

    private void criaArquivo(String arquivo, byte[] dados) {
        FileImageOutputStream imageOutput;
        try {
            imageOutput = new FileImageOutputStream(new File(arquivo));
            imageOutput.write(dados, 0, dados.length);
            imageOutput.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(PhotoController.class.getName()).log(Level.SEVERE, null, ex);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Caminho não encontrado!", "Erro"));
        } catch (IOException ex) {
            Logger.getLogger(PhotoController.class.getName()).log(Level.SEVERE, null, ex);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao criar arquivo!", "Erro"));
        }
    }

    public void recortar() {
        verificaExistenciaArquivo(arquivoFotoRecortada);
        fotoRecortada = "fotoRecortada" + getNumeroRandomico() + ".png";
        arquivoFotoRecortada = servletContext.getRealPath(File.separator + "imagens" + File.separator + "tmp" + File.separator + fotoRecortada);
        criaArquivo(arquivoFotoRecortada, imagemRecortada.getBytes());
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Foto RECORTADA com sucesso!", "Informação"));
    }

    public void oncapture(CaptureEvent captureEvent) {
        verificaExistenciaArquivo(arquivoFoto);
        foto = "foto" + getNumeroRandomico() + ".png";
        arquivoFoto = servletContext.getRealPath(File.separator + "imagens" + File.separator + "tmp" + File.separator + foto);
        criaArquivo(arquivoFoto, captureEvent.getData());
        exibeImagemCapturada = true;
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Foto CAPTURADA com sucesso!", "Informação"));
    }

    private void verificaExistenciaArquivo(String arquivo) {
        if (arquivo != null) {
            File file = new File(arquivo);
            if (file.exists()) {
                file.delete();
            }
        }
    }

    public PhotoController() {
        exibeImagemCapturada = false;
        servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
    }

O método  recortar() é chamado sempre que recortamos a imagem na view e o oncapture() é acionado pelo componente photocam sempre que a função javascript capture() for chamada. Veja que uso nomes randomicos para as imagens criadas, este é um truque para evitar cache do imagecropper, já que não há esta propriedade neste componente.

Muito simples!

Abaixo o resultado:

Categorias:JSF