Android: Как заполнить цвет только для определенной части изображения?

У меня есть изображение:

Введите описание изображения здесь Теперь, я хочу, чтобы заполнить цвет для конкретной части этого изображения. Как если бы я выбрал синий цвет, и если я коснусь Cap, тогда кепка должна быть заполнена цветом Blue. То же самое должно произойти и с другой частью, такой как нос, рот, глаза и т. Д.

Итак, как можно использовать Android?

Может ли кто-нибудь помочь мне помочь.

обновленный

Я попытался реализовать алгоритм FloodFill в своем приложении. Глянь сюда

Но после этого я получил исключение вроде:

03-09 17:45:16.260: ERROR/AndroidRuntime(2558): java.lang.IllegalStateException 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at android.graphics.Bitmap.setPixel(Bitmap.java:847) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at com.project.fingerpaint.FinderPaintDemo.FloodFill(FinderPaintDemo.java:284) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at com.project.fingerpaint.FinderPaintDemo.access$3(FinderPaintDemo.java:272) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at com.project.fingerpaint.FinderPaintDemo$MyView.onTouchEvent(FinderPaintDemo.java:187) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at android.view.View.dispatchTouchEvent(View.java:3766) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:863) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:863) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:863) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:863) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:863) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1671) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at android.app.Activity.dispatchTouchEvent(Activity.java:2086) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1655) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at android.view.ViewRoot.handleMessage(ViewRoot.java:1785) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at android.os.Handler.dispatchMessage(Handler.java:99) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at android.os.Looper.loop(Looper.java:123) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at android.app.ActivityThread.main(ActivityThread.java:4627) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at java.lang.reflect.Method.invokeNative(Native Method) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at java.lang.reflect.Method.invoke(Method.java:521) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 03-09 17:45:16.260: ERROR/AndroidRuntime(2558): at dalvik.system.NativeStart.main(Native Method) 

Теперь, что неправильно в моем коде?

Пожалуйста, помогите мне в этом состоянии.

Благодарю.

Используйте FloodFill Algoritham для этого

Используйте эту ссылку

Ссылка

Пожалуйста, проголосуйте, если это работает для вас. Это полный код заполнения цвета на изображении ниже:

Изображение для заполнения: http://i.stack.imgur.com/7rita.jpg

main.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_horizontal" android:orientation="vertical" > <RelativeLayout android:id="@+id/relative_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_weight="1" > <ImageView android:id="@+id/coringImage" android:layout_width="300dp" android:layout_height="300dp" /> </RelativeLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/btn_red" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="red" /> <Button android:id="@+id/btn_yellow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="yellow" /> <Button android:id="@+id/btn_blue" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="blue" /> </LinearLayout> </LinearLayout> 

Класс активности

 public class FillColorActivity extends Activity implements OnTouchListener { private RelativeLayout drawingLayout; private MyView myView; Button red, blue, yellow; Paint paint; /** Called when the activity is first created. */ /* * * private ImageView imageView; private Canvas cv; private Bitmap mask, * original, colored; private int r,g,b; private int sG, sR, sB; */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); myView = new MyView(this); drawingLayout = (RelativeLayout) findViewById(R.id.relative_layout); drawingLayout.addView(myView); red = (Button) findViewById(R.id.btn_red); blue = (Button) findViewById(R.id.btn_blue); yellow = (Button) findViewById(R.id.btn_yellow); red.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { paint.setColor(Color.RED); } }); yellow.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { paint.setColor(Color.YELLOW); } }); blue.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { paint.setColor(Color.BLUE); } }); } public class MyView extends View { private Path path; Bitmap mBitmap; ProgressDialog pd; final Point p1 = new Point(); Canvas canvas; // Bitmap mutableBitmap ; public MyView(Context context) { super(context); paint = new Paint(); paint.setAntiAlias(true); pd = new ProgressDialog(context); paint.setStyle(Paint.Style.STROKE); paint.setStrokeJoin(Paint.Join.ROUND); paint.setStrokeWidth(5f); mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.cartoon).copy(Bitmap.Config.ARGB_8888, true); this.path = new Path(); } @Override protected void onDraw(Canvas canvas) { this.canvas = canvas; paint.setColor(Color.GREEN); canvas.drawBitmap(mBitmap, 0, 0, paint); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: p1.x = (int) x; p1.y = (int) y; final int sourceColor = mBitmap.getPixel((int) x, (int) y); final int targetColor = paint.getColor(); new TheTask(mBitmap, p1, sourceColor, targetColor).execute(); invalidate(); } return true; } public void clear() { path.reset(); invalidate(); } public int getCurrentPaintColor() { return paint.getColor(); } class TheTask extends AsyncTask<Void, Integer, Void> { Bitmap bmp; Point pt; int replacementColor, targetColor; public TheTask(Bitmap bm, Point p, int sc, int tc) { this.bmp = bm; this.pt = p; this.replacementColor = tc; this.targetColor = sc; pd.setMessage("Filling...."); pd.show(); } @Override protected void onPreExecute() { pd.show(); } @Override protected void onProgressUpdate(Integer... values) { } @Override protected Void doInBackground(Void... params) { FloodFill f = new FloodFill(); f.floodFill(bmp, pt, targetColor, replacementColor); return null; } @Override protected void onPostExecute(Void result) { pd.dismiss(); invalidate(); } } } // flood fill public class FloodFill { public void floodFill(Bitmap image, Point node, int targetColor, int replacementColor) { int width = image.getWidth(); int height = image.getHeight(); int target = targetColor; int replacement = replacementColor; if (target != replacement) { Queue<Point> queue = new LinkedList<Point>(); do { int x = node.x; int y = node.y; while (x > 0 && image.getPixel(x - 1, y) == target) { x--; } boolean spanUp = false; boolean spanDown = false; while (x < width && image.getPixel(x, y) == target) { image.setPixel(x, y, replacement); if (!spanUp && y > 0 && image.getPixel(x, y - 1) == target) { queue.add(new Point(x, y - 1)); spanUp = true; } else if (spanUp && y > 0 && image.getPixel(x, y - 1) != target) { spanUp = false; } if (!spanDown && y < height - 1 && image.getPixel(x, y + 1) == target) { queue.add(new Point(x, y + 1)); spanDown = true; } else if (spanDown && y < height - 1 && image.getPixel(x, y + 1) != target) { spanDown = false; } x++; } } while ((node = queue.poll()) != null); } } } @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub return false; } } 

Используйте FloodFill.

  FloodFill f= new FloodFill(); f.floodFill(bmp,pt,targetColor,replacementColor); public class FloodFill { public void floodFill(Bitmap image, Point node, int targetColor, int replacementColor) { int width = image.getWidth(); int height = image.getHeight(); int target = targetColor; int replacement = replacementColor; if (target != replacement) { Queue<Point> queue = new LinkedList<Point>(); do { int x = node.x; int y = node.y; while (x > 0 && image.getPixel(x - 1, y) == target) { x--; } boolean spanUp = false; boolean spanDown = false; while (x < width && image.getPixel(x, y) == target) { image.setPixel(x, y, replacement); if (!spanUp && y > 0 && image.getPixel(x, y - 1) == target) { queue.add(new Point(x, y - 1)); spanUp = true; } else if (spanUp && y > 0 && image.getPixel(x, y - 1) != target) { spanUp = false; } if (!spanDown && y < height - 1 && image.getPixel(x, y + 1) == target) { queue.add(new Point(x, y + 1)); spanDown = true; } else if (spanDown && y < height - 1 && image.getPixel(x, y + 1) != target) { spanDown = false; } x++; } } while ((node = queue.poll()) != null); } } } 

Я подозреваю, что исходное растровое изображение было создано в режиме только для чтения. Вероятно, это причина исключения в setPixel (). Вы можете изменить это с помощью параметров BitmapFactory:

 opt = new BitmapFactory.Options(); // force RGBA pixel format even for 8-bit grey scale image files. opt.inPreferredConfig = Bitmap.Config.ARGB_8888; // want to modify the bitmap content. opt.inMutable = true; Bitmap bitmap=BitmapFactory.decodeFile("clown.png", opt); 
Intereting Posts
Android: как получить доступ к таблице контактов SIM с помощью SDK? Сохранение изображения из эскиза обработки Android Как отправлять / получать данные с помощью телефона bluetooth android на медицинское оборудование, имеющее Bluetooth Почему React Native's .flowconfig игнорирует файлы .android.js? Android: передача объектов между фрагментами Как я могу перенести действие на фронт из фоновой службы Как очистить файлы cookie и кеширование веб-браузера на Android, если вы не находитесь в веб-просмотре? Предупреждение pthread_create для android Как остановить запуск WebView от SL4A от скрытия панели уведомлений? Android Studio показывает, что ограничение inotify предупреждения слишком низкое Google Cloud Messaging – сообщения, которые иногда не принимаются, пока не изменилось состояние сети Комбинируйте низкую энергию iBeacon bluetooth с Android 4.3 Android: выберите изображение из галереи, затем обведите его и покажите в изображении ZipCode из местоположения Настольный webkit-эквивалент addJavascriptInterface () от Android?