use*_*104 4 android canvas android-layout android-imageview
我正在开发一个可以在其上绘制线条的自定义图像视图,问题是绘图区域大小与位图大小不完全相同.
例如,在另一个应用程序中,它看起来像:

但是,在我的应用程序中,它看起来像

这是我的程序,似乎位图不适合画布.谢谢你的帮助
public class DrawingView extends View {
//drawing path
private Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xFF660000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
public DrawingView(Context context, AttributeSet attrs){
super(context, attrs);
setupDrawing();
}
//setup drawing
private void setupDrawing(){
//prepare for drawing and setup paint stroke properties
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(15.0f);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
//size assigned to view
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
//draw the view - will be called after touch event
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher), 0, 0, canvasPaint);
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
//register user touches as drawing action
@Override
public boolean onTouchEvent(MotionEvent event) {
float touchX = event.getX();
float touchY = event.getY();
//respond to down, move and up events
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
drawPath.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
drawPath.lineTo(touchX, touchY);
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
break;
default:
return false;
}
//redraw
invalidate();
return true;
}
//update color
public void setColor(String newColor){
invalidate();
paintColor = Color.parseColor(newColor);
drawPaint.setColor(paintColor);
}
//start new drawing
public void startNew(){
drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
invalidate();
}
}
Run Code Online (Sandbox Code Playgroud)
我找到了类似的教程代码,问题是触摸事件有bug,它在操作栏中计算,其余的UI元素因此触摸很奇怪.建议看看
http://www.java2s.com/Code/Android/2D-Graphics/DrawonPictureandsave.htm
所以,这个主题的目标是解决方案
1)可绘制的图像
2)可缩放和平移(可以使用库)(当活动变焦,变焦,非活动变焦,绘制时)
可以参考屏幕截图1的想法
非常感谢您的帮助
ani*_*nil 13
您可以通过创建自己的ImageView来避免计算样本中其他UI项的坐标.试试这个代码Activity:
public class DrawOnBitmapActivity extends Activity implements OnClickListener
{
DrawableImageView choosenImageView;
Button choosePicture;
Button savePicture;
Bitmap bmp;
Bitmap alteredBitmap;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
choosenImageView = (DrawableImageView) this.findViewById(R.id.ChoosenImageView);
choosePicture = (Button) this.findViewById(R.id.ChoosePictureButton);
savePicture = (Button) this.findViewById(R.id.SavePictureButton);
savePicture.setOnClickListener(this);
choosePicture.setOnClickListener(this);
}
public void onClick(View v)
{
if (v == choosePicture)
{
Intent choosePictureIntent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(choosePictureIntent, 0);
}
else if (v == savePicture)
{
if (alteredBitmap != null)
{
ContentValues contentValues = new ContentValues(3);
contentValues.put(Media.DISPLAY_NAME, "Draw On Me");
Uri imageFileUri = getContentResolver().insert(
Media.EXTERNAL_CONTENT_URI, contentValues);
try {
OutputStream imageFileOS = getContentResolver()
.openOutputStream(imageFileUri);
alteredBitmap
.compress(CompressFormat.JPEG, 90, imageFileOS);
Toast t = Toast
.makeText(this, "Saved!", Toast.LENGTH_SHORT);
t.show();
} catch (Exception e) {
Log.v("EXCEPTION", e.getMessage());
}
}
}
}
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (resultCode == RESULT_OK) {
Uri imageFileUri = intent.getData();
try {
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
bmp = BitmapFactory
.decodeStream(
getContentResolver().openInputStream(
imageFileUri), null, bmpFactoryOptions);
bmpFactoryOptions.inJustDecodeBounds = false;
bmp = BitmapFactory
.decodeStream(
getContentResolver().openInputStream(
imageFileUri), null, bmpFactoryOptions);
alteredBitmap = Bitmap.createBitmap(bmp.getWidth(),
bmp.getHeight(), bmp.getConfig());
choosenImageView.setNewImage(alteredBitmap, bmp);
}
catch (Exception e) {
Log.v("ERROR", e.toString());
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
你必须activity_main稍微改变布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Choose Picture" android:id="@+id/ChoosePictureButton"/>
<ru.pristalovpavel.drawonimage.DrawableImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ChoosenImageView">
</ru.pristalovpavel.drawonimage.DrawableImageView>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Save Picture" android:id="@+id/SavePictureButton"/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
和你的自定义ImageView:
public class DrawableImageView extends ImageView implements OnTouchListener
{
float downx = 0;
float downy = 0;
float upx = 0;
float upy = 0;
Canvas canvas;
Paint paint;
Matrix matrix;
public DrawableImageView(Context context)
{
super(context);
setOnTouchListener(this);
}
public DrawableImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
setOnTouchListener(this);
}
public DrawableImageView(Context context, AttributeSet attrs,
int defStyleAttr)
{
super(context, attrs, defStyleAttr);
setOnTouchListener(this);
}
public void setNewImage(Bitmap alteredBitmap, Bitmap bmp)
{
canvas = new Canvas(alteredBitmap );
paint = new Paint();
paint.setColor(Color.GREEN);
paint.setStrokeWidth(5);
matrix = new Matrix();
canvas.drawBitmap(bmp, matrix, paint);
setImageBitmap(alteredBitmap);
}
@Override
public boolean onTouch(View v, MotionEvent event)
{
int action = event.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
downx = getPointerCoords(event)[0];//event.getX();
downy = getPointerCoords(event)[1];//event.getY();
break;
case MotionEvent.ACTION_MOVE:
upx = getPointerCoords(event)[0];//event.getX();
upy = getPointerCoords(event)[1];//event.getY();
canvas.drawLine(downx, downy, upx, upy, paint);
invalidate();
downx = upx;
downy = upy;
break;
case MotionEvent.ACTION_UP:
upx = getPointerCoords(event)[0];//event.getX();
upy = getPointerCoords(event)[1];//event.getY();
canvas.drawLine(downx, downy, upx, upy, paint);
invalidate();
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
final float[] getPointerCoords(MotionEvent e)
{
final int index = e.getActionIndex();
final float[] coords = new float[] { e.getX(index), e.getY(index) };
Matrix matrix = new Matrix();
getImageMatrix().invert(matrix);
matrix.postTranslate(getScrollX(), getScrollY());
matrix.mapPoints(coords);
return coords;
}
}
Run Code Online (Sandbox Code Playgroud)
eclipse中项目的所有源代码:link
更新:
新的源代码DrawableImageView!
更多信息在我的博客中.
| 归档时间: |
|
| 查看次数: |
9900 次 |
| 最近记录: |