Android Painting - canvas i spremanje

poruka: 9
|
čitano: 1.444
|
moderatori: XXX-Man, vincimus
1
+/- sve poruke
ravni prikaz
starije poruke gore
15 godina
neaktivan
offline
Android Painting - canvas i spremanje

Pozdrav.

Počeo sam učiti Android programiranje, i krenuo raditi jedan projektić.

Radi se o painting aplikaciji, koja bi imala mogućnost spremanja nacrtane slike.

Naišao sam na par problema, pa se valjda nađe neka dobra duša tu na Bugu da pomogne.

 

1. Imam path "putanja", i paint "boja". Napravio sam popup menu za mijenjanje boje, i debljine brusha. Međutim, kad god promijenim boju ili debljinu, kad krenem nastaviti crtati, i ono prošlo što je nacrtano, oboji se u tu novu boju / promijeni debljinu. Jel ja sad trebam napraviti array pathova ili kako već?

 

2. Kod popup menu-a, stavio sam da iskače kad se dugo drži pritisak na canvas, međutim on mi se uvijek na istom mjestu pojavljuje, a ne pojavljuje se tamo gdje je držan klik. Kako to riješiti?

 

3. Zanima me koji je najbolji način, i kako ustvari spremiti sliku (ono šta je nacrtano na canvasu) klikom na button.

 

Svaka pomoć je dobrodošla.

Puno hvala, unaprijed :)

Pozdrav!

 
0 0 hvala 1
15 godina
neaktivan
offline
Android Painting - canvas i spremanje

Jel mi actually može ko pomoći?

 
0 0 hvala 0
15 godina
neaktivan
offline
Android Painting - canvas i spremanje
Poruka je uređivana zadnji put ned 18.8.2013 13:02 (Hambrle).
 
0 0 hvala 0
17 godina
offline
Re: Android Painting - canvas i spremanje

Daj molim te ono što si mi poslao na PM, postaj ovdje samo bez pastebin-a.

'Genius might be the ability to say a profound thing in a simple way' Charles Bukowski
15 godina
neaktivan
offline
Re: Android Painting - canvas i spremanje
dado2202 kaže...

Daj molim te ono što si mi poslao na PM, postaj ovdje samo bez pastebin-a.

Ono što sam ti poslao na PM je stara verzija koja nema spojen path i paint. 

Sad sam napravio novu klasu mojaPutanja koja extenda path i još joj dodao bojaPutanje, tako da za svaki path mogu imati njegovu boju.

Ja se nadam da je to ok.

Ali evo ti kod sa pastebina:

 

///////////////////////////////////////////////////////////////////////////////////

//////////////////////////////// KLASA mojaPUTANJA ////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////

 

package primjer.crtanje;

 

import android.graphics.Paint;

import android.graphics.Path;

 

public class mojaPutanja extends Path {

     public Paint bojaPutanje;

 

     public mojaPutanja(Paint boja){

         bojaPutanje=boja;

     }

}

 

//////////////////////////////////////////////////////////////////////////////////////

////////////////////////KLASA CRTANJEVIEW (GDJE SE SVE ODVIJA ////////////////////////

//////////////////////////////////////////////////////////////////////////////////////

 

 

package primjer.crtanje;

 

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.util.ArrayList;

import java.util.Vector;

 

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Path;

import android.os.Handler;

import android.util.AttributeSet;

import android.util.Log;

import android.util.Pair;

import android.view.MotionEvent;

import android.view.View;

 

public class CrtanjeView extends View {

 

     public static Paint boja;

     public static mojaPutanja putanja;

     private Paint krugBoja;

     private Path krugPutanja;

     public static int LONG_PRESS_TIME = 500;

 

//////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////DEKLARACIJA NIZA PUTANJA///////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////

     public static ArrayList<mojaPutanja> paths = new ArrayList<mojaPutanja>();

 

     // Varijabla za custom klasu QuickAction

     QuickAction qa;

 

     final Handler _handler = new Handler();

     Runnable _longPressed = new Runnable() {

         public void run() {

 

             // Poziva se metoda za prikaz QuickAction-a. ToÄŤnije, prikaĹľe se grid s 1 redom i 3 stupca, a u svakom stupcu je po jedan button

             qa.pokazi();

 

             Log.i("hepek", "Pritisnuto je dugo");

         }

     };

 

     public void dodajFunkcija() {

         Log.d("hepek", "pozvano");

         for (Path p : paths) {

       p.reset();

         }

         putanja.reset();

         postInvalidate();

     }

 

     public void ocistiFunkcija() {

         Log.d("hepek", "pozvano");

         for (Path p : paths) {

       p.reset();

         }

         postInvalidate();

     }

 

     private void inicijalizacija(Context k) {

         // // Inicijalizacija varijabli poput boje, boje kruga, putanje i sl.

         // stvari //////

         boja = new Paint();

         krugBoja = new Paint();

         krugPutanja = new Path();        

         // Inicijalizacija qa varijable. ProsljeÄ‘uje joj se trenutni View

         qa = new QuickAction(this);

 

     }

 

     private void postaviKist() {

 

         // ///////// Postavljanje kista //////////

 

         boja.setAntiAlias(true);

         boja.setColor(Color.BLUE);

         // Da boja bude kist:

         boja.setStyle(Paint.Style.STROKE);

         // Da kist bude okruglog oblika:

         boja.setStrokeJoin(Paint.Join.ROUND);

         // Debljina kista

         boja.setStrokeWidth(5f);

 

//////////////////////////////////////////////////////////////////////////////////////

///////////////PRAVLJENJE POČETNE PUTANJE, I DODAVANJE ISTE U NIZ/////////////////////

//////////////////////////////////////////////////////////////////////////////////////

         putanja = new mojaPutanja(boja);

         paths.add(putanja);

 

         // ///////// Postavljanje kruga oko kista //////////

         krugBoja.setAntiAlias(true);

         krugBoja.setColor(Color.CYAN);

         krugBoja.setStyle(Paint.Style.STROKE);

         krugBoja.setStrokeJoin(Paint.Join.MITER);

         krugBoja.setStrokeWidth(4f);

     }

 

     public CrtanjeView(Context k, AttributeSet set) {

         super(k, set);

         inicijalizacija(k);

         postaviKist();

     }

 

     @Override

     protected void onDraw(Canvas canvas) { 

 

///////////////////////////////////////////////////////////////////////////////////

////////////////////PROLAZAK KROZ VEKTOR I CRTANJE PATHOVA/////////////////////////

///////////////////////////////////////////////////////////////////////////////////

 

         for (mojaPutanja p : paths)

         {

       canvas.drawPath(p, p.bojaPutanje);

       canvas.drawPath(krugPutanja, krugBoja);

         }

 

     }

 

     @Override

     public boolean onTouchEvent(MotionEvent e) {

 

         float tackaX = e.getX();

         float tackaY = e.getY();

 

         switch (e.getAction()) {

         case MotionEvent.ACTION_DOWN:

             putanja.moveTo(tackaX, tackaY);

             _handler.postDelayed(_longPressed, LONG_PRESS_TIME);

             return true;

 

         case MotionEvent.ACTION_MOVE:

 

             putanja.lineTo(tackaX, tackaY);

             krugPutanja.reset();

             krugPutanja.addCircle(tackaX, tackaY, 25, Path.Direction.CW);

             _handler.removeCallbacks(_longPressed);

             break;

 

         case MotionEvent.ACTION_UP:

//////////////////////////////////////////////////////////////////////////////////////////

////SVAKI PUT KAD SE PUSTI KLIK DA SE NAPRAVI NOVA PUTANJA SA BOJOM I DODA SE U VEKTOR////

//////////////////////////////////////////////////////////////////////////////////////////

 

         putanja = new mojaPutanja(boja);

         //putanja.bojaPutanje = boja;

         paths.add(putanja);

             krugPutanja.reset();

             _handler.removeCallbacks(_longPressed);

             break;

 

         default:

             return false;

         }

 

         postInvalidate();

         return true;

     }

 

}

 

 

/////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////ON CLICK LISTENER ZA MIJENJANJE BOJE /////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////

 

         ok.setOnClickListener(new OnClickListener() {

             @Override

             public void onClick(View v) {

                 int id = rg.getCheckedRadioButtonId();

 

                 switch(id){

                 case R.id.rbCrvena:

                     CrtanjeView.boja.setColor(Color.RED);

                     CrtanjeView.putanja = new mojaPutanja(CrtanjeView.boja);

                   CrtanjeView.paths.add(CrtanjeView.putanja);

                     break;

                 case R.id.rbPlava:

                     CrtanjeView.boja.setColor(Color.BLUE);

                     CrtanjeView.putanja = new mojaPutanja(CrtanjeView.boja);

                   CrtanjeView.paths.add(CrtanjeView.putanja);

                     break;

                 case R.id.rbZelena:

                     CrtanjeView.boja.setColor(Color.BLACK);

                     CrtanjeView.putanja = new mojaPutanja(CrtanjeView.boja);

                   CrtanjeView.paths.add(CrtanjeView.putanja);

                     break;

                 }

 

                 tv.setText(Integer.toString(id));

                 dialog.dismiss();

             }

         });

 

Ajd nadam se da ćeš mi uspjet pomoći jer se mučim na ovom već par dana a planirao sam ga davno završiti 

 

17 godina
offline
Re: Android Painting - canvas i spremanje

Jednostavno.

 

Prvo i najbitnije, morao bi si kod Jave malo pogledati kako radi inicijalizacija objekata, varijable su ti samo "pointeri" na objekte itd. Sad se fakat ne mogu sjetiti neke literature gdje je to točno pokriveno, ali imaš u svakoj knjigi o javi.

 

Na početku klase deklariraš jednu instancu klase Paint(nenicijaliziranu).

 

    public static Paint boja;

     public static mojaPutanja putanja;

     private Paint krugBoja;

     private Path krugPutanja;

     public static int LONG_PRESS_TIME = 500;

 

Nakon toga inicijaliziraš sve te instance uključujući i Paint (boja objekt)

 

private void inicijalizacija(Context k) {

         // // Inicijalizacija varijabli poput boje, boje kruga, putanje i sl.

         // stvari //////

        boja = new Paint();

         krugBoja = new Paint();

         krugPutanja = new Path();        

         // Inicijalizacija qa varijable. ProsljeÄ‘uje joj se trenutni View

         qa = new QuickAction(this);

 

     }

 

Tu je još "recimo" sve ok(ja to ne bi tako napravio, ali ajde zamislimo to kao "default boju koju dobiva svaki path").

 

Evo sad dolazimo do problema

 

private void postaviKist() {

 

         // ///////// Postavljanje kista //////////

 

         boja.setAntiAlias(true);

         boja.setColor(Color.BLUE);

         // Da boja bude kist:

         boja.setStyle(Paint.Style.STROKE);

         // Da kist bude okruglog oblika:

         boja.setStrokeJoin(Paint.Join.ROUND);

         // Debljina kista

         boja.setStrokeWidth(5f);

 

//////////////////////////////////////////////////////////////////////////////////////

///////////////PRAVLJENJE POČETNE PUTANJE, I DODAVANJE ISTE U NIZ/////////////////////

//////////////////////////////////////////////////////////////////////////////////////

         putanja = new mojaPutanja(boja);

         paths.add(putanja);

 

         // ///////// Postavljanje kruga oko kista //////////

         krugBoja.setAntiAlias(true);

         krugBoja.setColor(Color.CYAN);

         krugBoja.setStyle(Paint.Style.STROKE);

         krugBoja.setStrokeJoin(Paint.Join.MITER);

         krugBoja.setStrokeWidth(4f);

     }

 

Taj isti objekt (tj. pokazivač na objekt) dodijeljuješ svojoj klasi koja ti označava putanju. Drugim riječima, sve putanje imaju referencu na isti boja objekt. Znači ako se taj boja objekt negdje promijeni, on se mijenja na svim instancama path objekta.

 

Isto to i malo niže u kodu imaš

 

//////////////////////////////////////////////////////////////////////////////////////////

////SVAKI PUT KAD SE PUSTI KLIK DA SE NAPRAVI NOVA PUTANJA SA BOJOM I DODA SE U VEKTOR////

//////////////////////////////////////////////////////////////////////////////////////////

 

         putanja = new mojaPutanja(boja);

         //putanja.bojaPutanje = boja;

         paths.add(putanja);

             krugPutanja.reset();

             _handler.removeCallbacks(_longPressed);

             break;

 

         default:

             return false;

         }

 

Onda kada radiš obradu onClick eventa

 

                     case R.id.rbCrvena:

                     CrtanjeView.boja.setColor(Color.RED);

                     CrtanjeView.putanja = new mojaPutanja(CrtanjeView.boja);

                   CrtanjeView.paths.add(CrtanjeView.putanja);

                     break;

                 case R.id.rbPlava:

                     CrtanjeView.boja.setColor(Color.BLUE);

                     CrtanjeView.putanja = new mojaPutanja(CrtanjeView.boja);

                   CrtanjeView.paths.add(CrtanjeView.putanja);

                     break;

                 case R.id.rbZelena:

                     CrtanjeView.boja.setColor(Color.BLACK);

                     CrtanjeView.putanja = new mojaPutanja(CrtanjeView.boja);

                   CrtanjeView.paths.add(CrtanjeView.putanja);

                     break;

                 }

Ustvari mijenjaš boja objekt koji je dodijeljen svima putanjama, pa se automatski svima mijenja boja

 

Na tvoju sreću Android to ima lijepo riješeno da ti nova Paint instanca lagano naslijedi postojeću, npr ovako izmjeniš postojeće dijelove koda (imaš na dva mjesta inicijalizaciju mojaPutanja klase)

 

         putanja = new mojaPutanja(new Paint(boja));

         paths.add(putanja);

 

 

P.S. Kada nazivaš nešto u svojoj aplikaciji, odluči se odmah na početku da li će to biti na HR ili na ENG, pa se onda toga drži kroz kod, jer ponekad zna biti malo zbunjujuće.

'Genius might be the ability to say a profound thing in a simple way' Charles Bukowski
15 godina
neaktivan
offline
Re: Android Painting - canvas i spremanje
dado2202 kaže...

Znao sam da je neki problem u nedovoljnom poznavanju jave.

Slomio sam se tražeći grešku, a nisam ni mislio da tako funkcioniraju varijable u javi.

Ne znam, hvala je jednostavno malo, ti si life-savior...

P.S. Hvala na savjetu :)

15 godina
neaktivan
offline
Android Painting - canvas i spremanje

Jel znaš kako bih mogao napraviti eraser?

Kad korisnik odabere button "eraser" ja radim ovo:

 

CrtanjeView.boja.setMaskFilter(null);

CrtanjeView.boja.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

CrtanjeView.boja.setAlpha(0xFF);//transperent color

CrtanjeView.putanja = new mojaPutanja(new Paint(CrtanjeView.boja));

CrtanjeView.paths.add(CrtanjeView.putanja);

 

Ali iz nekog razloga mi ostavlja crnu liniju, međutim, kad snimim sliku, tamo gdje je crna linija zapravo bude obrisano. 

Dakle, eraser radi kako spada kad se snimi i sve to, samo dok sam u aplikaciji i dok brišem, ostavlja se crna linija.

 
0 0 hvala 0
17 godina
offline
Re: Android Painting - canvas i spremanje

Mislim da ti je to zato jer nemaš pozadinu. (znaš dok u photoshopu brišeš nešto, onda dobivaš one kockice - tako oni označavaju da je sve obrisano).

 

Mislim da bi ti najbolje bilo da si postaviš neku pozadinu i nakon toga kada brišeš brišeš u boji te pozadine.

'Genius might be the ability to say a profound thing in a simple way' Charles Bukowski
1
Nova poruka
E-mail:
Lozinka:
 
vrh stranice