我正在使用具有着色功能的应用程序。用户可以对此图像执行平移和缩放。我正在使用this库为图像添加缩放效果。
但问题是当我缩放图像时,我无法对图像的特定区域进行着色。在小视图中,它工作得很完美,但是当我在区域上进行缩放时,它会将颜色填充到不同区域而不是触摸区域。
原因只是因为即使我在顶部放大图像也不会缩放原始图像。我搜索并发现this回答这是我遇到的同样问题,但我不知道在activity.java文件中何处以及如何使用它。
这是我的ActivityClass
package com.coloringbook;
import java.io.File;
import java.io.IOException;
import android.app.Activity;
import android.app.WallpaperManager;
import android.content.Intent;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Shader.TileMode;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.Images;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import android.widget.LinearLayout.LayoutParams;
import com.coloringbook.R;
import com.onesignal.OneSignal;
public class Game extends Activity implements View.OnLongClickListener, View.OnClickListener, View.OnTouchListener {
private TouchImageView image;
Bitmap bm_iv; //bitmap for image view for coloring
int bm_iv_dx; //sizes
int bm_iv_dy;
int[] pixels; //of bm_iv; need to fill by color
final int[] colors_base = {0xff0000,0xff8000,0xffff00,0x80ff00,0x00ff00,0x00ff80,0x00ffff,0x0080ff,
0x0000ff,0x8000ff,0xff00ff,0xff0080,0x888888}; //default palette
final int btn_num = colors_base.length;
int[] colors_gradient = new int[btn_num]; //gradient palette, will generate dynamically
Bitmap bm_gradient; //to draw gradient and fill gradient buttons
Bitmap[] bm_button_on = new Bitmap[btn_num*2]; //bitmaps for color buttons
Bitmap[] bm_button_off = new Bitmap[btn_num*2];
Bitmap[] bm_button_pressed = new Bitmap[btn_num*2];
int size_button; // size of color button, depend of screen resolution
final int color_gradient_shift = 3; // to avoid dark colors
int color_selected; // index of current color
int color_base_selected; // index of base color
static int bitmap_saved_counter; // to generate name to save on SD card
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Data.SetFullScreenMode(this);
setContentView(R.layout.game);
Data.ShowAdMob(this);
image = (TouchImageView) findViewById(R.id.book);
bm_gradient = Bitmap.createBitmap(btn_num+2+color_gradient_shift, 1, Config.ARGB_8888);
LinearLayout ll_root = (LinearLayout)findViewById(R.id.mainLayout);
ll_root.setOnLongClickListener( this );
DisplayMetrics dm = getResources().getDisplayMetrics();
size_button = dm.widthPixels/btn_num;
int i;
LinearLayout ll_base = new LinearLayout(this);
ll_base.setOrientation(LinearLayout.HORIZONTAL);
ll_base.setLayoutParams(new LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
LinearLayout ll_gradient = new LinearLayout(this);
ll_gradient.setOrientation(LinearLayout.HORIZONTAL);
ll_gradient.setLayoutParams(new LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
for( i = 0; i < btn_num; i++){
ImageButton ib = new ImageButton(this);
ib.setId( Data.id_image_begin+i);
ib.setPadding(0, 0, 0, 0);
ib.setBackgroundDrawable(null);
ib.setOnClickListener(this);
ll_base.addView(ib);
ib = new ImageButton(this);
ib.setId( Data.id_image_begin+i+btn_num);
ib.setPadding(0, 0, 0, 0);
ib.setBackgroundDrawable(null);
ib.setOnClickListener(this);
ll_gradient.addView(ib);
}
ll_root.addView(ll_base);
ll_root.addView(ll_gradient);
UpdateButtons();
InitImage("");
}
void InitImage( String filePath ){
bm_iv = null;
File file = new File(filePath);
if( file.isFile() ){
Options opts = new Options();
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
opts.inScaled = false;
bm_iv = BitmapFactory.decodeFile( filePath, opts);
}
if( bm_iv == null ){
int id = getResources().getIdentifier( "book_"+ Data.image_index, "drawable", getPackageName());
bm_iv = BitmapFactory.decodeResource( getResources(), id);
}
bm_iv_dx = bm_iv.getWidth();
bm_iv_dy = bm_iv.getHeight();
DisplayMetrics dm = getResources().getDisplayMetrics();
if( dm.widthPixels >= bm_iv_dx && dm.heightPixels >= bm_iv_dy ){
}else{
float scale_x = (float) bm_iv_dx/(float) dm.widthPixels;
float scale_y = (float) bm_iv_dy/(float) dm.heightPixels;
float scale = Math.max(scale_x, scale_y);
bm_iv_dx/=scale;
bm_iv_dy/=scale;
bm_iv = Bitmap.createScaledBitmap(bm_iv, bm_iv_dx, bm_iv_dy, true);
}
bm_iv = bm_iv.copy(Config.ARGB_8888, true); //need convert to mutable bitmap
ImageView iv = (ImageView)findViewById(R.id.book);
iv.setImageBitmap( bm_iv );
pixels = new int[bm_iv_dx*bm_iv_dy];
int x, y;
//initialization black contours
for( y = 0; y < bm_iv_dy; y++ ){
for( x = 0; x < bm_iv_dx; x++ ){
int color = bm_iv.getPixel(x, y);
if(Color.red(color) <= 0x80 && Color.green(color) <= 0x80 && Color.blue(color) <= 0x80){
pixels[y*bm_iv_dx+x] = -1;
}else{
pixels[y*bm_iv_dx+x] = 0;
}
}
}
iv.setOnTouchListener( this );
}
static int ColorShader( int color, int devider){
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
r -= r/devider;
g -= g/devider;
b -= b/devider;
return Color.argb(255, r, g, b);
}
boolean IsValidXY( int x, int y){
if( 0 <= x && x < bm_iv_dx && 0 <= y && y < bm_iv_dy ){
return true;
}else{
return false;
}
}
boolean FillPixel( int x, int y, int color_fill ){
if( IsValidXY(x,y) ){
if( pixels[y*bm_iv_dx+x] == 0 ){
pixels[y*bm_iv_dx+x] = color_fill;
return true;
}else{
return false;
}
}else{
return false;
}
}
//create rounded square solid color bitmap
Bitmap GetButtonBitmap( int size_button, int color, int round, int border ){
Bitmap bm = Bitmap.createBitmap( size_button, size_button, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(color);
paint.setAlpha(255);
paint.setStyle(Paint.Style.FILL);
c.drawRoundRect(new RectF(border,border,size_button-border, size_button-border), round, round, paint);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1);
paint.setColor(ColorShader(color,2));
c.drawRoundRect(new RectF(border,border,size_button-border, size_button-border), round, round, paint);
return bm;
}
//set images to all color buttons
void SetButtons(){
for( int i = 0; i < btn_num; i++){
ImageButton ib = (ImageButton) findViewById(Data.id_image_begin+i);
StateListDrawable states = new StateListDrawable();
Drawable d = new BitmapDrawable( getResources(), bm_button_pressed[i]);
states.addState(new int[] {android.R.attr.state_pressed}, d);
d = new BitmapDrawable( getResources(), (color_selected == i) ? bm_button_on[i]:bm_button_off[i]);
states.addState(new int[]{}, d );
ib.setImageDrawable(states);
ib = (ImageButton) findViewById(Data.id_image_begin+i+btn_num);
states = new StateListDrawable();
d = new BitmapDrawable( getResources(), bm_button_pressed[i+btn_num]);
states.addState(new int[] {android.R.attr.state_pressed}, d);
d = new BitmapDrawable( getResources(), (color_selected == i+btn_num) ? bm_button_on[i+btn_num]:bm_button_off[i+btn_num]);
states.addState(new int[]{}, d );
ib.setImageDrawable(states);
}
}
//regenerate gradient colors and create solid color bitmaps to image buttons
public void UpdateButtons(){
//set gradient by base color
int i;
int color = 0xff000000|colors_base[color_base_selected];
Canvas canvas = new Canvas(bm_gradient);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
LinearGradient shader = new LinearGradient(0, 0, bm_gradient.getWidth(), 0, new int[] { Color.BLACK, color, Color.WHITE }, null, TileMode.CLAMP);
paint.setShader(shader);
canvas.drawPaint(paint);
for( i = 0; i < btn_num; i++){
colors_gradient[i] = bm_gradient.getPixel(i+1+color_gradient_shift, 0);
}
int round = size_button/8; //of square
int border = size_button/16; //to small not selected buttons
for( i = 0; i < btn_num; i++){
bm_button_on[i] = GetButtonBitmap( size_button, colors_base[i], round, 0 );
bm_button_off[i] = GetButtonBitmap( size_button, colors_base[i], round, border );
bm_button_pressed[i] = GetButtonBitmap( size_button, ColorShader(colors_base[i],2), round, 0 );
bm_button_on[ btn_num+i] = GetButtonBitmap( size_button, colors_gradient[i], round, 0 );
bm_button_off[btn_num+i] = GetButtonBitmap( size_button, colors_gradient[i], round, border );
bm_button_pressed[btn_num+i] = GetButtonBitmap( size_button, ColorShader(colors_gradient[i],2), round, 0 );
}
SetButtons();
}
@Override
public void onClick( View v ) { //color buttons
int index = v.getId() - Data.id_image_begin;
color_selected = index;
if( index < btn_num ){
color_base_selected = index;
UpdateButtons();
}else{
SetButtons();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.game_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected( MenuItem item ) {
switch( item.getItemId() ){
case R.id.load_image:
startActivityForResult( new Intent( Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI), 0);
break;
case R.id.save_to_galary:
Images.Media.insertImage( getContentResolver(), bm_iv, getString(R.string.app_name)+(bitmap_saved_counter++), null);
break;
case R.id.set_as_wallpaper_landscape:
case R.id.set_as_wallpaper_portrait:
DisplayMetrics dm = getResources().getDisplayMetrics();
Bitmap bm;
int add_x, add_y;
if( item.getItemId() == R.id.set_as_wallpaper_landscape ){
bm = Bitmap.createBitmap( dm.heightPixels*2, dm.widthPixels*2, Bitmap.Config.ARGB_8888);
}else{
bm = Bitmap.createBitmap( dm.widthPixels*2, dm.heightPixels*2, Bitmap.Config.ARGB_8888);
}
add_x = (bm.getWidth() - bm_iv.getWidth())/2;
add_y = (bm.getHeight() - bm_iv.getHeight())/2;
bm.eraseColor( bm_iv.getPixel(0, 0) );
Canvas canvas = new Canvas(bm);
canvas.drawBitmap(bm_iv, add_x, add_y, null);
WallpaperManager wm = WallpaperManager.getInstance(getApplicationContext());
try {
wm.setBitmap(bm);
} catch (IOException e) {
Toast.makeText( this, "Upps. Can not set as wallpaper.", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
break;
}
return true;
}
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent){
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
InitImage(filePath);
}
}
public boolean onLongClick( View view) { // on screen
this.openOptionsMenu();
return false;
}
@Override
public void openOptionsMenu() { //need to work menu on some devices, fix the bug
Configuration config = getResources().getConfiguration();
if((config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) > Configuration.SCREENLAYOUT_SIZE_LARGE) {
int originalScreenLayout = config.screenLayout;
config.screenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
super.openOptionsMenu();
config.screenLayout = originalScreenLayout;
} else {
super.openOptionsMenu();
}
}
@Override
public boolean onTouch(View v, MotionEvent event) { // on coloring book
if (event.getAction() == MotionEvent.ACTION_DOWN) {
int x_touch = (int)event.getX();
int y_touch = (int)event.getY();
if( IsValidXY(x_touch,y_touch) == false || pixels[y_touch*bm_iv_dx+x_touch] == -1 ){ //touch on contour
return false;
}
ImageView iv_touch = (ImageView)findViewById(R.id.book);
int x,y;
//clear
for( y = 0; y < bm_iv_dy; y++ ){
for( x = 0; x < bm_iv_dx; x++ ){
if( pixels[y*bm_iv_dx+x] != -1 ){
pixels[y*bm_iv_dx+x] = 0;
}
}
}
int color_fill = 0;
if( color_selected < btn_num){
color_fill = colors_base[color_selected];
}else{
color_fill = colors_gradient[color_selected-btn_num];
}
color_fill |= 0xff000000;
pixels[y_touch*bm_iv_dx+x_touch] = color_fill;
//filler
int xx,yy;
while( true ){
boolean go = false;
for( y = 0; y < bm_iv_dy; y++ ){
for( x = 0; x < bm_iv_dx; x++ ){
if( pixels[y*bm_iv_dx+x] == color_fill ){
go |= FillPixel(x,y-1,color_fill);
go |= FillPixel(x+1,y-1,color_fill);
go |= FillPixel(x+1,y,color_fill);
go |= FillPixel(x+1,y+1,color_fill);
go |= FillPixel(x,y+1,color_fill);
go |= FillPixel(x-1,y+1,color_fill);
go |= FillPixel(x-1,y,color_fill);
go |= FillPixel(x-1,y-1,color_fill);
if( IsValidXY(x-1,y) && pixels[y*bm_iv_dx+x-1] == color_fill ){
xx = x-2;
while( FillPixel(xx--,y,color_fill) ){}
}
if( IsValidXY(x+1,y) && pixels[y*bm_iv_dx+x+1] == color_fill ){
xx = x+2;
while( FillPixel(xx++,y,color_fill) ){}
}
if( IsValidXY(x,y-1) && pixels[(y-1)*bm_iv_dx+x] == color_fill ){
yy = y-2;
while( FillPixel(x,yy--,color_fill) ){}
}
if( IsValidXY(x,y+1) && pixels[(y+1)*bm_iv_dx+x] == color_fill ){
yy = y+2;
while( FillPixel(x,yy++,color_fill) ){}
}
}
}
}
if( go == false ){
break;
}
}
//update pixels
for( y = 0; y < bm_iv_dy; y++ ){
for( x = 0; x < bm_iv_dx; x++ ){
if( pixels[y*bm_iv_dx+x] == color_fill ){
bm_iv.setPixel(x, y, color_fill);
}
}
}
iv_touch.invalidate();
}
return false;
}
}
以下是我用于缩放的ImageTouchView.java
如果有人能帮助我,我真的很感激。