Een afbeelding vastleggen en bijsnijden met de camera van het apparaat

Veel Android-apparaten zijn uitgerust met ingebouwde camera's. In deze zelfstudie zullen we de basistechniek voor het vastleggen van een afbeelding met behulp van de Android-camera bestuderen en deze vervolgens bijsnijden met apps die de gebruiker al op zijn apparaat heeft geïnstalleerd. Onderweg zal ik ook laten zien hoe u verantwoording kunt afleggen voor gebruikers van wie de apparaten de afbeeldings- of bijsnijdacties niet ondersteunen.


Stap 1: start een nieuw Android-project

Maak een nieuw Android-project in Eclipse of uw gekozen IDE. Voeg in uw hoofdactiviteitsklasse de volgende importinstructies toe na de pakketdeclaratie:

 import android.app.Activity; importeer android.content.ActivityNotFoundException; importeer android.content.Intent; importeer android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; importeer android.provider.MediaStore; import android.view.View; import android.view.View.OnClickListener; importeer android.widget.Button; import android.widget.ImageView; import android.widget.Toast;

Hiermee kunnen we afbeeldingen vastleggen, bijsnijden en weergeven binnen de app. Open het XML-bestand van de strings van uw toepassing, dat u moet vinden in de map "res / values". Voeg de volgende tekenreeksen toe:

 Leg een foto vast om bij te snijden! afbeelding Start de camera

We zullen deze strings gebruiken binnen de gebruikersinterface.


Stap 2: Implementeer de app-lay-out

Laten we de lay-out van de app ontwerpen. Open uw hoofd XML-bestand, dat zich in de map "res / layout" zou moeten bevinden. Gebruik een lineaire lay-out als volgt, die Eclipse mogelijk al heeft geleverd:

  

Voeg in de lineaire lay-out de volgende tekstweergave toe:

 

Hier tonen we wat informatieve tekst met behulp van een tekenreeks die we hebben gedefinieerd in het XML-tekenreeksen. Na de tekstweergave voegt u een knop als volgt toe:

 

Met de ID-waarde kunnen we de knop in Java identificeren, zodat we kunnen reageren op klikken. Nogmaals, we gebruiken een string die we al in XML gedefinieerd hebben. Voeg ten slotte na de knop een afbeeldingsweergave toe:

 

We plaatsen de afbeelding die is vastgelegd door de gebruiker met de camera van het apparaat in deze Beeldweergave, met behulp van de ID-waarde om deze in Java te identificeren. We gebruiken een van de strings als een beschrijving van de inhoud en als achtergrond een bruikbare bron die we vervolgens zullen creëren. Als u wilt dat de afbeeldingsweergave wordt uitgerekt om de beschikbare ruimte te vullen, wijzigt u de kenmerken width en height in "fill_parent" in plaats van "wrap_content" - houd er rekening mee dat hierdoor de afbeelding kan worden weergegeven met slechte kwaliteit.

Maak een nieuw XML-bestand voor elke achtergrond die je kunt tekenen en noem deze "pic_border.xml" om overeen te komen met de waarde die we gebruikten in de layout Lay-out afbeelding.. De gemakkelijkste manier om dit te doen, is door het bestand in één uittrekbare map te maken, de XML-code erin te kopiëren, het op te slaan en het vervolgens naar de andere te maken mappen te kopiëren.

Gebruik de volgende XML in uw nieuwe "pic_border" tekenbare bestand:

      

Het gebruik van een tekenbare achtergrondbron is volledig optioneel, dus voel je vrij om dit onderdeel weg te laten. Zo ziet de app eruit wanneer deze wordt gestart:


Stap 3: Reageren op gebruikersklikken

Verleng in de Activiteitsklasse van uw app de openingsklasse-declaratie-regel als volgt:

 public class ShootAndCropActivity breidt activiteiten uit OnClickListener 

Verander de klassenaam die bij u past. Voeg in de activiteit "onCreate" het volgende toe na de bestaande code die de superklassemethode aanroept en de inhoudlay-out instelt, die Eclipse zou moeten hebben ingevuld:

 // een verwijzing naar de UI-knop ophalen Knop captureBtn = (Knop) findViewById (R.id.capture_btn); // greepknop klikt captureBtn.setOnClickListener (this);

Hier instrueren we de klas gewoon om knopknoppen te verwerken. De gebruiker drukt op de knop om de camera te starten. Nu moeten we een "onClick" -methode aanbieden. Voeg het als volgt toe, na de methode "onCreate":

 public void onClick (View v) if (v.getId () == R.id.capture_btn) 

Binnen de "als" -instructie zullen we implementeren met behulp van de camera.


Stap 4: Start de camera

Voeg de volgende instantievariabelen toe boven aan uw klassendeclaratie vóór de methode "onCreate":

 // houd de vastlegging van de camera vast in de uiteindelijke int CAMERA_CAPTURE = 1; // gevangen beeld uri privé Uri picUri;

We zullen de eerste variabele gebruiken om de interactie van de gebruiker bij te houden terwijl ze naar de camera-app en terug navigeren. De tweede variabele slaat de URI van de vastgelegde afbeelding op. Voeg in de "if" -instructie in je "onClick" -methode de volgende code toe om de camera Intent te starten, inclusief in een "try" -blok:

 probeer // gebruik standaard intentie om een ​​afbeelding te vangen Intent captureIntent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE); // we zullen de geretourneerde gegevens afhandelen in onActivityResult startActivityForResult (captureIntent, CAMERA_CAPTURE); 

Wanneer deze code wordt uitgevoerd, wordt de camera-app van de gebruiker gestart en kunnen ze een foto maken. We behandelen de gebruiker die terugkeert van de camera-app in de methode "onActivityResult". Van daaruit kunnen we controleren of de gebruiker terugkeert vanuit deze intentie met behulp van de "CAMERA_CAPTURE" -variabele die we doorgeven bij het starten van de activiteit. Voordat we dat doen, moeten we echter omgaan met de situatie waarin het apparaat van de gebruiker de afbeelding niet ondersteunt die we hier hebben geprobeerd te starten. Na het blok "try" voegt u als volgt een "catch" toe:

 catch (ActivityNotFoundException anfe) // geeft een foutmelding weer String errorMessage = "Oeps - uw apparaat ondersteunt geen vastlegging van afbeeldingen!"; Toast toast = Toast.makeText (dit, errorMessage, Toast.LENGTH_SHORT); toast.show (); 

Telkens wanneer u probeert een Intent buiten uw eigen app te lanceren, is dit een voorzorgsmaatregel die u wellicht wilt nemen. Dit is met name het geval bij de bijsnijdactie die we later zullen onderzoeken, maar dit codepatroon is een goede gewoonte om over het algemeen te gebruiken, aangezien gebruikersapparaten sterk variëren. Wanneer de gebruiker de foto accepteert die ze hebben vastgelegd, keren ze terug naar de app.


Stap 5: haal de gemaakte afbeelding op

We hebben de camera-app gelanceerd met "startActivityForResult", dus we moeten nu het resultaat afhandelen. Voeg de methode "onActivityResult" na de "onClick" -methode als volgt toe:

 protected void onActivityResult (int requestCode, int resultCode, Intent data) if (resultCode == RESULT_OK) 

Voeg in de 'als'-instructie nog een toe om te controleren of we terugkomen van de camera-app, met behulp van de variabele die we hebben doorgegeven:

 // gebruiker keert terug van het vastleggen van een afbeelding met behulp van de camera if (requestCode == CAMERA_CAPTURE) 

We gaan ook terug naar de methode "onActivityResult" nadat de gebruiker zijn afbeelding heeft bijgesneden, dus we zullen later een "else if" toevoegen. Voeg in deze "als" -instructie de volgende code toe om de URI van de vastgelegde foto op te halen:

 // haal de Uri voor de vastgelegde afbeelding picUri = data.getData ();

Nu moeten we deze URI doorgeven aan een app die het kan bijsnijden. We zullen een hulpmethode gebruiken om dit te bereiken, dus voeg de volgende methodeaanroep toe:

 // voer de gewasbewerking uit performCrop ();

Stap 6: Snijd de gemaakte afbeelding bij

Voeg de helpermethode toe die we hebben genoemd na de methode "onActivityResult":

 private void performCrop () 

Binnen deze methode gaan we een Intent bellen om het bijsnijden uit te voeren, dus laten we blokken "try" en "catch" toevoegen voor het geval het gebruikersapparaat de crop-bewerking niet ondersteunt:

 probeer  catch (ActivityNotFoundException anfe) // toon een foutmelding String errorMessage = "Oeps - uw apparaat biedt geen ondersteuning voor de bijsnijdactie!"; Toast toast = Toast.makeText (dit, errorMessage, Toast.LENGTH_SHORT); toast.show (); 

We gebruiken dezelfde techniek die we hebben gebruikt bij het starten van de camera Intent. Als het gebruikersapparaat de crop-intentie niet ondersteunt, wordt er een foutbericht weergegeven. In het "try" -blok start je de Intent als volgt:

 // noem de standaardaanpassingsintentie (het gebruikersapparaat ondersteunt dit mogelijk niet) Intent cropIntent = new Intent ("com.android.camera.action.CROP"); // geef afbeeldingstype en Uri cropIntent.setDataAndType aan (picUri, "image / *"); // stel bijsnij-eigenschappen cropIntent.putExtra in ("bijsnijden", "waar"); // geef het aspect van de gewenste crop cropIntent.putExtra aan ("aspectX", 1); cropIntent.putExtra ("aspectY", 1); // geef uitvoer X en Y cropIntent.putExtra aan ("outputX", 256); cropIntent.putExtra ("outputY", 256); // gegevens ophalen bij return cropIntent.putExtra ("retourgegevens", waar); // start de activiteit - we handelen terug in onActivityResult startActivityForResult (cropIntent, PIC_CROP);

Hier stellen we verschillende eigenschappen in voor de bijgesneden afbeelding, waarmee de app wordt opgedragen om de resulterende afbeeldingsgegevens op te halen wanneer het bijsnijden voltooid is. Als u wilt dat de bijgesneden afbeeldingsdimensies hier anders uitzien, wijzigt u de regels "outputX" en "outputY" overeenkomstig. We noemen de Intent met "startActivityForResult", dus zal het resultaat opnieuw binnen "onActivityResult" worden opgehaald. Net als bij de Intent van de camera, passeren we een variabele om bij te houden van welke Intentie we terugkeren, dus voeg een variabelverklaring toe bovenaan de klas, naast de andere instantievariabelen:

 // houd bijsnijdende intentie bij laatste int PIC_CROP = 2;

Naast bijsnijden kan de gebruiker een gedeelte van de afbeelding selecteren.


Stap 7: Toon de bijgesneden afbeelding

Eindelijk kunnen we de bijgesneden afbeelding ophalen en weergeven in de app-gebruikersinterface. Binnen uw "onActivityResult" -methode voegt u na de "if" -instructie waarin u de aanvraagcode voor "CAMERA_CAPTURE" opzoekt, een "if else" -instructie toe die controleert op de "PIC_CROP" -code, in welk geval we terugkeren van de bewerking van het gewas :

 // gebruiker keert terug van bijsnijden van de afbeelding anders if (requestCode == PIC_CROP) 

In deze verklaring kunnen we de geretourneerde bijgesneden afbeelding als volgt ophalen:

 // haal de geretourneerde gegevens bij Bundle extras = data.getExtras (); // haal de bijgesneden bitmap Bitmap thePic = extras.getParcelable ("data");

We hebben nu de bijgesneden afbeelding van de gebruiker als een bitmap. Laten we het als volgt in de Beeldweergave weergeven:

 // een verwijzing ophalen naar de ImageView ImageView picView = (ImageView) findViewById (R.id.picture); // toon de geretourneerde bijgesneden afbeelding picView.setImageBitmap (thePic);

Nu wordt de bijgesneden afbeelding weergegeven in de gebruikersinterface van de app zodra de gebruiker terugkeert van het bijsnijden. Sla uw app op en voer hem uit op een echt apparaat om hem te testen.


Conclusie

In deze zelfstudie hebben we het basisproces voor vastleggen en bijsnijden binnen de Android SDK onderzocht. De bijsnijdactie in het bijzonder kan echter enigszins onvoorspelbaar zijn op de verschillende gebruikersapparaten die in bedrijf zijn. Veel verschillende apps kunnen de bijsnijdbewerking aan, dus sommige ontwikkelaars gebruiken een complexer algoritme om de gebruikerskeuzes op te lossen door deze apps aan de gebruiker voor te stellen als een lijst met opties om uit te kiezen. Welke apps de gebruikersomgeving ook biedt, het basisproces van vastleggen en bijsnijden blijft hetzelfde.