Ta opp og beskjære et bilde med enhetskameraet

Mange Android-enheter er utstyrt med innebygde kameraer. I denne veiledningen vil vi jobbe gjennom den grunnleggende teknikken for å fange et bilde ved hjelp av Android-kameraet, og deretter beskjære det ved hjelp av apper som brukeren allerede har installert på enheten. Underveis vil jeg også vise hvordan du skal redegjøre for brukere hvis enheter ikke støtter enten bildeopptak eller beskjæringshandlinger.


Trinn 1: Start et nytt Android-prosjekt

Opprett et nytt Android-prosjekt i Eclipse, eller din valgte IDE. I hovedaktivitetsklassen legger du til følgende importopplysninger etter pakkeerklæringen:

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

Disse vil tillate oss å utføre bildeopptak, beskjære og vise i appen. Åpne XML-filen for programmets strenger, som du finner i mappen "res / values". Legg til følgende strenger:

 Ta et bilde for å beskjære! Bilde Start kameraet

Vi bruker disse strengene i brukergrensesnittet.


Trinn 2: Implementér App Layout

La oss designe appoppsettet. Åpne din viktigste XML-fil, som skal være i "res / layout" -mappen. Bruk en lineær layout som følger, hvilken formørkelse kan allerede ha gitt:

  

I den lineære oppsettet legger du til følgende tekstvisning:

 

Her viser vi litt informativ tekst ved hjelp av en streng vi definerte i XML-filens strenger. Etter tekstvisningen legger du til en knapp som følger:

 

ID-verdien lar oss identifisere knappen i Java, slik at vi kan svare på klikk. Igjen bruker vi en streng vi allerede har definert i XML. Til slutt, etter knappen, legger du til et bildevisning:

 

Vi vil plassere bildet tatt av brukeren med deres enhetskamera inne i denne bildevisningen, ved hjelp av ID-verdien for å identifisere den i Java. Vi bruker en av strengene som en innholdsbeskrivelse og en bakgrunnsdragbar ressurs vi vil lage neste. Hvis du vil at bildevisningen skal strekke for å fylle ledig plass, endrer du bredden og høydeattributtene til "fill_parent" i stedet for "wrap_content" - husk at dette kan føre til at bildet vises som dårlig kvalitet.

For bakgrunnen som kan trekkes, opprett en ny XML-fil i hver av dine app-trekkbare mapper, navngi den "pic_border.xml" for å matche verdien vi brukte i bildevisning-layout-delen. Den enkleste måten å gjøre dette på er å lage filen i en trekkbar mappe, kopier XML-koden til den, lagre den, og kopier den deretter til de andre trekkbare mappene.

Bruk følgende XML i den nye "pic_border" -trekkbare filen:

      

Bruke en trekkbar bakgrunnsressurs er helt valgfri, så vær så snill å utelate denne delen. Slik ser appen ut når den lanseres:


Trinn 3: Svar på brukerklikk

I appen din Aktivitetsklasse, forlenge åpnings klassen deklarasjonslinjen som følger:

 offentlig klasse ShootAndCropActivity utvider Aktivitetsredskaper OnClickListener 

Endre klassenavnet slik at det passer deg selv. Inne i aktiviteten "onCreate" -metoden, legg til følgende etter at eksisterende kode kaller superclass-metoden og sett innholdsoppsettet, som Eclipse burde ha befolket:

 // Hent en referanse til UI-knappen Button captureBtn = (Button) findViewById (R.id.capture_btn); // håndtak knapp klikk captureBtn.setOnClickListener (dette);

Her lærer vi bare klassen å håndtere knappeklikk. Brukeren vil trykke på knappen for å starte kameraet. Nå må vi gi en "onClick" -metode. Legg til det som følger, etter "onCreate" -metoden:

 offentlig ugyldig påClick (Vis v) hvis (v.getId () == R.id.capture_btn) 

Inne i "if" -oppgaven, vil vi implementere ved hjelp av kameraet.


Trinn 4: Start kameraet

På toppen av klassedeklarasjonen din, før "onCreate" -metoden, legger du til følgende instansvariabler:

 // holde oversikt over kamerainfanget intent slutten int CAMERA_CAPTURE = 1; // fanget bilde uri privat Uri picUri;

Vi bruker den første variabelen for å holde oversikt over brukerens interaksjon når de navigerer til kameraets app og tilbake. Den andre variabelen lagrer URIen til det tatt bildet. Inne i "if" -oppgaven i "onClick" -metoden, legg til følgende kode for å starte kameraets Intent, inkludert det i en "prøve" -blokk:

 prøv // bruk standard hensikt å fange et bilde Intent captureIntent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE); // vi vil håndtere de returnerte dataene i onActivityResult startActivityForResult (captureIntent, CAMERA_CAPTURE); 

Når denne koden kjøres, starter brukerens kameraprogram, og de kan ta et bilde. Vi skal håndtere brukeren som returnerer fra kameraprogrammet innenfor "onActivityResult" -metoden. Derfra kan vi sjekke at brukeren kommer tilbake fra denne hensikten ved å bruke "CAMERA_CAPTURE" -variabelen vi passerer når aktiviteten starter. Men før vi gjør det, må vi håndtere situasjonen der brukerenheten ikke støtter bildeopptaket vi har forsøkt å lansere her. Etter "prøve" -blokken legger du til en "catch" som følger:

 fange (ActivityNotFoundException anfe) // vise en feilmelding String errorMessage = "Whoops - enheten din støtter ikke fange bilder!"; Toast toast = Toast.makeText (dette, errorMessage, Toast.LENGTH_SHORT); toast.show (); 

Når du prøver å lansere en Intent utenfor din egen app, er dette en forholdsregel du måtte ønske å ta. Dette er spesielt tilfellet med beskjæringsvirksomheten som vi vil undersøke senere, men dette kodemønsteret er en god vane å adoptere generelt, ettersom brukerenheter varierer sterkt. Når brukeren aksepterer bildet de har tatt, kommer de tilbake til appen.


Trinn 5: Hent oppfanget bilde

Vi lanserte kameraprogrammet ved hjelp av "startActivityForResult", slik at vi nå må håndtere resultatet. Legg til "onActivityResult" -metoden etter "onClick" -metoden som følger:

 beskyttet ugyldig onActivityResult (int requestCode, int resultCode, Intent data) hvis (resultCode == RESULT_OK) 

Inne i "if" -klæringen legger du til en annen for å sjekke at vi kommer tilbake fra kameraappen, ved hjelp av variabelen vi passerte:

 // brukeren kommer tilbake fra å fange et bilde ved hjelp av kameraet hvis (requestCode == CAMERA_CAPTURE) 

Vi kommer også tilbake til "onActivityResult" -metoden etter at brukeren beskjærer bildet sitt, så vi legger til et "annet hvis" senere. Inne i denne "if" -oppstillingen legger du til følgende kode for å hente URIen til det tatt bildet:

 // få Uri for det tatt bildet picUri = data.getData ();

Nå må vi sende denne URI til en app som kan beskjære den. Vi vil bruke en hjelpemetode for å oppnå dette, så legg til følgende metodeanrop:

 // utfør avlingen operasjon utførCrop ();

Trinn 6: Beskjær bildet

Legg til hjelpemetoden vi kalte etter metoden "onActivityResult":

 privat ugyldig utførelseCrop () 

Innenfor denne metoden skal vi kalle en hensikt å utføre avlingen, så la oss legge til "prøve" og "fange" blokker hvis brukeren ikke støtter avlingen.

 prøv  fangst (ActivityNotFoundException anfe) // viser en feilmelding String errorMessage = "Whoops - enheten din støtter ikke avlingen handling!"; Toast toast = Toast.makeText (dette, errorMessage, Toast.LENGTH_SHORT); toast.show (); 

Vi bruker den samme teknikken vi brukte når vi startet kameraet Intent. Hvis brukerenheten ikke støtter beskjæringen Intent, vil de se en feilmelding. Inne i "prøve" -blokken, start Intent slik:

 // ring standard avsetning for avlinger (brukerenheten støtter kanskje ikke den) Intent cropIntent = new Intent ("com.android.camera.action.CROP"); // angi bildetype og Uri cropIntent.setDataAndType (picUri, "image / *"); // sett beskjæreegenskaper cropIntent.putExtra ("crop", "true"); // angi aspekt av ønsket avlingavgrøntIntent.putExtra ("aspektX", 1); cropIntent.putExtra ("aspektY", 1); // angi utgang X og Y cropIntent.putExtra ("outputX", 256); cropIntent.putExtra ("outputY", 256); // hente data på return cropIntent.putExtra ("return-data", true); // start aktiviteten - vi håndterer retur i onActivityResult startActivityForResult (cropIntent, PIC_CROP);

Her setter vi ulike egenskaper for det beskjære bildet, og instruerer appen om å hente de resulterende bildedataene når beskjæringen er fullført. Hvis du vil at de beskjedne bildedimensjonene skal avvike fra dette, må du endre "outputX" og "outputY" linjene tilsvarende. Vi kaller hensikten ved å bruke "startActivityForResult", så vil hente resultatet i "onActivityResult" igjen. Som med kameraets Intent, passerer vi en variabel for å holde oversikt over hvilken Intent vi kommer tilbake fra, så legg til en variabel deklarasjon øverst i klassen ved siden av de andre instansvariablene:

 // holde styr på beskjæringsintensjonen endelig int PIC_CROP = 2;

I tillegg til beskjæring kan brukeren velge et område på bildet.


Trinn 7: Vis det beskårne bildet

Til slutt kan vi hente det beskårne bildet og vise det i app-brukergrensesnittet. I "OnActivityResult" -metoden, etter "Hvis" -oppgaven der du sjekker for "CAMERA_CAPTURE" -forespørselskoden, legger du til et "if else" -utvalg som kontrollerer "PIC_CROP" -koden, i så fall vender vi tilbake fra beskjæringsoperasjonen :

 // brukeren kommer tilbake fra å beskjære bildet annet hvis (requestCode == PIC_CROP) 

Inne i denne utsagnet kan vi hente det returnerte beskjære bildet som følger:

 // få de returnerte dataene Bundle extras = data.getExtras (); // få den beskårne bitmappen Bitmap thePic = extras.getParcelable ("data");

Vi har nå brukerens beskjærte bilde som en Bitmap. La oss vise det i bildevisningen som følger:

 // hente en referanse til ImageView ImageView picView = (ImageView) findViewById (R.id.picture); // vise det returnerte beskjærte bildet picView.setImageBitmap (thePic);

Nå vises det beskjære bildet i app-brukergrensesnittet så snart brukeren returnerer fra beskjæring. Lagre og kjøre appen din på en faktisk enhet for å teste den.


Konklusjon

I denne opplæringen har vi utforsket grunnleggende fangst- og avlingerprosessen i Android SDK. Imidlertid kan beskjæringsaksjonen være litt uforutsigbar på de forskjellige brukerenhetene i drift. Mange forskjellige applikasjoner kan håndtere beskjæringsoperasjonen, slik at noen utviklere vedtar en mer komplisert algoritme for å løse brukerens valg, og presentere disse appene til brukeren som en liste over alternativer å velge mellom. Uansett hvilke applikasjoner brukermiljøet gir, forblir den grunnleggende prosessen med fangst og avling det samme.