Android 如何创建绘制位图?
这是我的完整画布视图,我没有创建位图,我真的不知道怎么做。如果你理解它,如果你能帮助我,请做它。提前谢谢你!save函数在FirstActivity中,它表示位图为空Android 如何创建绘制位图?,android,canvas,bitmap,save,Android,Canvas,Bitmap,Save,这是我的完整画布视图,我没有创建位图,我真的不知道怎么做。如果你理解它,如果你能帮助我,请做它。提前谢谢你!save函数在FirstActivity中,它表示位图为空 public class CanvasView extends View{ private static final float STROKE_WIDTH = 5f; private static final float HALF_STROKE_WIDTH = STROKE_WIDTH/2; Paint erasePaint =
public class CanvasView extends View{
private static final float STROKE_WIDTH = 5f;
private static final float HALF_STROKE_WIDTH = STROKE_WIDTH/2;
Paint erasePaint = new Paint();
Paint paint = new Paint();
Path path = new Path();
float lastTouchX,lastTouchY;
AlertDialog.Builder alert;
RectF ovalRectangle = new RectF();
RectF dirtyRect = new RectF();
MyRectangle myRectangle;
MyOval myOval;
MyCircle myCircle;
MyFreehand myFreehand;
MyLine myLine;
MyEraser myEraser;
List<MyEraser> eraserList = new ArrayList<MyEraser>();
List<MyLine> lineList = new ArrayList<MyLine>();
List<MyFreehand> freehandList = new ArrayList<MyFreehand>();
List<MyCircle> circleList = new ArrayList<MyCircle>();
List<MyOval> ovalList = new ArrayList<MyOval>();
List<MyRectangle> rectangleList = new ArrayList<MyRectangle>();
public boolean dashedLine = false;
public DashPathEffect dashEffect = new DashPathEffect(new float[]{20,30}, 0);
private Paint mBitmapPaint;
private Bitmap mBitmap;
public String textValue;
public CanvasView(Context context, AttributeSet attrs) {
super(context, attrs);
setBackgroundColor(Color.WHITE);
if (android.os.Build.VERSION.SDK_INT >= 11)
{
turnOffHardwareAcc();
}
erasePaint.setColor(Color.WHITE);
//erasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
erasePaint.setAntiAlias(true);
erasePaint.setStyle(Paint.Style.STROKE);
erasePaint.setStrokeJoin(Paint.Join.ROUND);
erasePaint.setStrokeWidth(12);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(STROKE_WIDTH);
paint.setTextSize(34);
setMode(7);//default = 7 - free hand;
mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
/* input dialog*/
//setInputDialog();
}
EditText input;
public void setInputDialog(){
alert = new AlertDialog.Builder(getContext());
alert.setTitle("Title");
alert.setMessage("Write text");
// Set an EditText view to get user input
input = new EditText(getContext());
alert.setView(input);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
textValue= input.getText().toString();
Toast.makeText(getContext(), textValue, Toast.LENGTH_SHORT).show();
// Do something with value!
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
}
});
//alert.show();
}
public void setDashLine(){
dashedLine = true;
paint = new Paint();
paint.setPathEffect(dashEffect);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(STROKE_WIDTH);
}
public void setNormalLine(){
//paint.setColor(Color.BLACK);
dashedLine = false;
paint.setPathEffect(null);
paint.setStyle(Paint.Style.STROKE);
paint.setPathEffect(null);
paint.setAntiAlias(true);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(STROKE_WIDTH);
}
@TargetApi(11)
public void turnOffHardwareAcc() // to enable dashed lines
{
this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
//public void setPaint(int color,)
@TargetApi(11)
protected void onDraw(Canvas canvas) {
if(dashedLine){
paint.setPathEffect(dashEffect);
}
else {
paint.setPathEffect(null);
}
if(bitmap!=null){
canvas.drawBitmap(bitmap, 0, 0, paint);
for(MyCircle circle:circleList){// draw circles
myCanvas.drawCircle(getCircleMidPointX(circle.firstX, circle.lastX),getCircleMidPointY(circle.firstY, circle.lastY),circle.radius,myPaint);
}
}
for(MyLine line:lineList){ //draw lines
if(dashedLine)
line.paint.setPathEffect(dashEffect);
else
line.paint.setPathEffect(null);
canvas.drawLine(line.xStart, line.yStart, line.xEnd, line.yEnd, line.paint);
}
for(MyCircle circle:circleList){// draw circles
canvas.drawCircle(getCircleMidPointX(circle.firstX, circle.lastX),getCircleMidPointY(circle.firstY, circle.lastY),circle.radius,paint);
}
for(MyOval oval:ovalList){
if(dashedLine)
oval.paint.setPathEffect(dashEffect);
else oval.paint.setPathEffect(null);
ovalRectangle.set(oval.getX1(),oval.getY1(),oval.getX2(),oval.getY2());
canvas.drawOval(ovalRectangle, oval.paint);
}
for(MyRectangle rectangle:rectangleList){
if(dashedLine)
rectangle.paint.setPathEffect(dashEffect);
else rectangle.paint.setPathEffect(null);
canvas.drawRect(rectangle.getX1(),rectangle.getY1(),rectangle.getX2(),rectangle.getY2(),rectangle.paint);
}
for(MyEraser e:eraserList){
canvas.drawPath(e.p,erasePaint);
invalidate();
}
if(textValue!= null)
canvas.drawText(textValue, xStart, yStart, paint);
canvas.drawPath(path, paint);
//path.reset();
}
final OnTouchListener drawLineListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
FirstActivity.ll.setVisibility(LinearLayout.GONE);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
myLine = new MyLine();
myLine.xStart = event.getX();
myLine.yStart = event.getY();
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
myLine.xEnd = event.getX();
myLine.yEnd = event.getY();
invalidate();
lineList.add(myLine);
break;
default:
Log.d("mock it up", "Unknown touch event " + event.toString());
return false;
}
return true;
}
};
final OnTouchListener drawDashedLineListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
FirstActivity.ll.setVisibility(LinearLayout.GONE);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
break;
default:
Log.d("mock it up", "Unknown touch event " + event.toString());
return false;
}
return true;
}
};
final OnTouchListener drawCircleListener = new OnTouchListener(){
public boolean onTouch(View v, MotionEvent event) {
FirstActivity.ll.setVisibility(LinearLayout.GONE);
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// path.moveTo(eventX, eventY);
Toast.makeText(getContext(), "action down - circle",Toast.LENGTH_SHORT).show();
myCircle = new MyCircle();
myCircle.firstX = eventX;
myCircle.firstY = eventY;
// There is no end point yet, so don't waste cycles invalidating.
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
myCircle.lastX = eventX;
myCircle.lastY = eventY;
myCircle.radius = getRadius(myCircle.firstX,myCircle.firstY,myCircle.lastX,myCircle.lastY);
circleList.add(myCircle);
invalidate();
break;
default:
Log.d("mock it up", "Unknown touch event " + event.toString());
return false;
}
return true;
}
};
final OnTouchListener drawOvalListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
FirstActivity.ll.setVisibility(LinearLayout.GONE);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
myOval = new MyOval();
myOval.setX1(event.getX());
myOval.setY1(event.getY());
// There is no end point yet, so don't waste cycles invalidating.
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
myOval.setX2(event.getX());
myOval.setY2(event.getY());
invalidate();
ovalList.add(myOval);
default:
Log.d("mock it up", "Unknown touch event " + event.toString());
return false;
}
}
};
final OnTouchListener drawRectangleListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
FirstActivity.ll.setVisibility(LinearLayout.GONE);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
myRectangle = new MyRectangle();
myRectangle.setX1(event.getX());
myRectangle.setY1(event.getY());
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
myRectangle.setX2(event.getX());
myRectangle.setY2(event.getY());
invalidate();
rectangleList.add(myRectangle);
break;
default:
Log.d("mock it up", "Unknown touch event " + event.toString());
return false;
}
return true;
}
};
final OnTouchListener eraseListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// erasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
//FirstActivity.ll.setVisibility(LinearLayout.GONE);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
myEraser = new MyEraser();
lastTouchX = event.getX();
lastTouchY = event.getY();
myEraser.mouseDown(event.getX(), event.getY());
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
resetDirtyRect(event.getX(),event.getY());
int historySize = event.getHistorySize();
for(int i=0;i<historySize;i++){
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
expandDirtyRect(historicalX, historicalY);
myEraser.mouseUp(historicalX, historicalY);
}
myEraser.mouseUp(event.getX(), event.getY());
eraserList.add(myEraser);
break;
default:
Log.d("mock it up", "Unknown touch event " + event.toString());
return false;
}
invalidate(
(int) (dirtyRect.left - HALF_STROKE_WIDTH),
(int) (dirtyRect.top - HALF_STROKE_WIDTH),
(int) (dirtyRect.right + HALF_STROKE_WIDTH),
(int) (dirtyRect.bottom + HALF_STROKE_WIDTH));
lastTouchX = event.getX();
lastTouchY = event.getY();
return true;
}
};
final OnTouchListener drawFreeHandListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
FirstActivity.ll.setVisibility(LinearLayout.GONE);
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// path.reset();
path.moveTo(eventX, eventY);
lastTouchX = eventX;
lastTouchY = eventY;
// There is no end point yet, so don't waste cycles invalidating.
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
// Start tracking the dirty region.
resetDirtyRect(eventX, eventY);
// When the hardware tracks events faster than they are delivered, the
// event will contain a history of those skipped points.
int historySize = event.getHistorySize();
for (int i = 0; i < historySize; i++) {
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
expandDirtyRect(historicalX, historicalY);
path.lineTo(historicalX, historicalY);
}
// After replaying history, connect the line to the touch point.
path.lineTo(eventX, eventY);
//path.reset();
break;
default:
Log.d("mock it up", "Unknown touch event " + event.toString());
return false;
}
// Include half the stroke width to avoid clipping.
invalidate(
(int) (dirtyRect.left - HALF_STROKE_WIDTH),
(int) (dirtyRect.top - HALF_STROKE_WIDTH),
(int) (dirtyRect.right + HALF_STROKE_WIDTH),
(int) (dirtyRect.bottom + HALF_STROKE_WIDTH));
lastTouchX = eventX;
lastTouchY = eventY;
return true;
}
};
float xStart,yStart;
final OnTouchListener textListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
FirstActivity.ll.setVisibility(LinearLayout.GONE);
// Toast.makeText(getContext(), "add some text", Toast.LENGTH_SHORT).show();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//
setInputDialog();
xStart = event.getX();
yStart = event.getY();
alert.show();
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
// setInputDialog();
break;
default:
Log.d("mock it up", "Unknown touch event " + event.toString());
return false;
}
return true;
}
};
/**
* Called when replaying history to ensure the dirty region includes all
* points.
*/
private void expandDirtyRect(float historicalX, float historicalY) {
if (historicalX < dirtyRect.left) {
dirtyRect.left = historicalX;
} else if (historicalX > dirtyRect.right) {
dirtyRect.right = historicalX;
}
if (historicalY < dirtyRect.top) {
dirtyRect.top = historicalY;
} else if (historicalY > dirtyRect.bottom) {
dirtyRect.bottom = historicalY;
}
}
/**
* Resets the dirty region when the motion event occurs.
*/
private void resetDirtyRect(float eventX, float eventY) {
// The lastTouchX and lastTouchY were set when the ACTION_DOWN
// motion event occurred.
dirtyRect.left = Math.min(lastTouchX, eventX);
dirtyRect.right = Math.max(lastTouchX, eventX);
dirtyRect.top = Math.min(lastTouchY, eventY);
dirtyRect.bottom = Math.max(lastTouchY, eventY);
}
public void setMode(int mode){
switch(mode){
case 1://draw line
Toast.makeText(getContext(), "draw line", Toast.LENGTH_SHORT).show();
setOnTouchListener(drawLineListener);
break;
case 2://draw dashed line
Toast.makeText(getContext(), "dashed line", Toast.LENGTH_SHORT).show();
break;
case 3:// draw circle
setOnTouchListener(drawCircleListener);
break;
case 4: //draw oval
setOnTouchListener(drawOvalListener);
break;
case 5: //draw rectangle
setOnTouchListener(drawRectangleListener);
break;
case 6: //erase
setOnTouchListener(eraseListener);
break;
case 7: //free-hand
setOnTouchListener(drawFreeHandListener);
break;
case 8:
setOnTouchListener(textListener);
break;
}
}
private Bitmap bitmap;
private Canvas myCanvas;
public Paint myPaint;
public void setImage(Bitmap b){
Toast.makeText(getContext(), "set Bitmap",Toast.LENGTH_SHORT).show();
bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
myCanvas = new Canvas(bitmap);
myPaint = new Paint();
myPaint.setColor(Color.YELLOW);
myPaint.setAntiAlias(true);
myPaint.setStrokeWidth(8);
invalidate();
}
public void changeColor(int color){
paint = new Paint(paint);
paint.setColor(color);
//myPaint.setColor(color);
}
public float getRadius(float x1,float y1,float x2,float y2){
float r = (float) (Math.sqrt((double)(Math.pow((y2-y1), 2.0)+Math.pow((x2-x1), 2.0)))/2);
return r;
}
public float getCircleMidPointX(float x1,float x2){
return (x1+x2)/2;
}
public float getCircleMidPointY(float y1,float y2){
return (y1+y2)/2;
}
}
public类CanvasView扩展视图{
专用静态最终浮动行程_宽度=5f;
专用静态最终浮动半冲程宽度=冲程宽度/2;
油漆=新油漆();
油漆=新油漆();
路径路径=新路径();
浮动lastTouchX,lastTouchY;
AlertDialog.Builder警报;
RectF ovalRectangle=新的RectF();
RectF dirtyRect=新的RectF();
我的矩形我的矩形;
肌膜肌膜;
我的圈子我的圈子;
我的徒手;
糜棱线;
髓鞘酶;
List eraserList=new ArrayList();
List lineList=new ArrayList();
List freehandList=new ArrayList();
List circleList=新建ArrayList();
List ovalList=new ArrayList();
List rectangleList=新建ArrayList();
公共布尔虚线=false;
公共DashPathEffect dashEffect=新的DashPathEffect(新浮点[]{20,30},0);
私人油漆;
私有位图mBitmap;
公共字符串文本值;
公共画布视图(上下文、属性集属性){
超级(上下文,attrs);
setBackgroundColor(颜色:白色);
如果(android.os.Build.VERSION.SDK_INT>=11)
{
关闭硬件eacc();
}
橡皮擦油漆。设置颜色(颜色。白色);
//橡皮擦paint.setXfermode(新的PorterDuffXfermode(PorterDuff.Mode.CLEAR));
橡皮擦油漆。setAntiAlias(真);
擦除Paint.setStyle(Paint.Style.STROKE);
橡皮擦油漆.设置行程连接(油漆.连接.圆形);
擦除油漆。设置行程宽度(12);
油漆。设置颜色(颜色。黑色);
绘制.设置样式(绘制.样式.笔划);
paint.setAntiAlias(真);
绘制.设置行程连接(绘制.连接.圆形);
油漆。设置行程宽度(行程宽度);
油漆.尺寸(34);
setMode(7);//默认值=7-自由手;
mBitmap=Bitmap.createBitmap(320480,Bitmap.Config.ARGB_8888);
mBitmapPaint=新油漆(油漆抖动标志);
/*输入对话框*/
//setInputDialog();
}
编辑文本输入;
public void setInputDialog(){
alert=新建AlertDialog.Builder(getContext());
警报。设置标题(“标题”);
alert.setMessage(“写入文本”);
//设置EditText视图以获取用户输入
输入=新编辑文本(getContext());
alert.setView(输入);
alert.setPositiveButton(“确定”,新的DialogInterface.OnClickListener(){
public void onClick(对话框接口对话框,int whichButton){
textValue=input.getText().toString();
Toast.makeText(getContext(),textValue,Toast.LENGTH_SHORT).show();
//做一些有价值的事情!
}
});
alert.setNegativeButton(“取消”,新建DialogInterface.OnClickListener()){
public void onClick(对话框接口对话框,int whichButton){
//取消了。
}
});
//alert.show();
}
public void setDashLine(){
虚线=真;
油漆=新油漆();
paint.setPathEffect(dashEffect);
绘制.设置样式(绘制.样式.笔划);
paint.setAntiAlias(真);
绘制.设置行程连接(绘制.连接.圆形);
油漆。设置行程宽度(行程宽度);
}
公共void setNormalLine(){
//油漆。设置颜色(颜色。黑色);
虚线=假;
paint.setPathEffect(空);
绘制.设置样式(绘制.样式.笔划);
paint.setPathEffect(空);
paint.setAntiAlias(真);
绘制.设置行程连接(绘制.连接.圆形);
油漆。设置行程宽度(行程宽度);
}
@塔吉塔皮(11)
public void turnOffHardwareAcc()//启用虚线
{
this.setLayerType(View.LAYER\u TYPE\u软件,null);
}
//公共void setPaint(内部颜色)
@塔吉塔皮(11)
受保护的void onDraw(画布){
如果(虚线){
paint.setPathEffect(dashEffect);
}
否则{
paint.setPathEffect(空);
}
if(位图!=null){
drawBitmap(位图,0,0,绘制);
对于(MyCircle circle:circleList){//绘制圆
myCanvas.drawCircle(getCircleMidPointX(circle.firstX,circle.lastX),getCircleMidPointY(circle.firstY,circle.lastY),circle.radius,myPaint);
}
}
对于(MyLine-line:lineList){//绘制线
如果(虚线)
line.paint.setPathEffect(dashEffect);
其他的
line.paint.setPathEffect(null);
canvas.drawLine(line.xStart、line.yStart、line.xEnd、line.yEnd、line.paint);
}
对于(MyCircle circle:circleList){//绘制圆
canvas.drawCircle(getCircleMidPointX(circle.firstX,circle.lastX),getCircleMidPointY(circle.firstY,circle.lastY),circle.radius,paint);
}
用于(MyOval椭圆形:椭圆形){
如果(虚线)
椭圆形。绘制。设置路径效果(dashEffect);
else oval.paint.setPathEffect(null);
ovalRectangle.set(oval.getX1()、oval.getY1()、oval.getX2()、oval.getY2());
画布.绘制椭圆形(椭圆形导电角,椭圆形.绘制);
}
用于(MyRectangle矩形:矩形列表){
如果(虚线)
矩形.paint.setPathEffect(dashEffect);
else矩形.paint.setPathEffect(null);
drawRect(rectangle.getX1()、rectangle.getY1()、rectangle.getX2()、rectangle.getY2()、rectangle.paint);
}
for(MyEraser e:橡皮擦列表){
画布。绘图路径(e.p,橡皮擦油漆);
使无效();
}
if(textValue!=null)
drawText(textValue、xStart、yStart、paint);
画布.绘制路径(路径,绘制);
//path.reset();
}
最终OnTouchListener drawLineListener=新OnTouchListener(){
公共布尔onTouch(视图v,运动事件){
FirstActivity.ll.setVisibility(LinearLayout.GONE);
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
myLine=新的myLine();
myLine.xStart=event.getX();
myLine.yStart=event.getY();
返回true;
case MotionEvent.ACTION\u移动:
case MotionEvent.ACTION\u UP:
myLine.xEnd=event.getX();
myLine.yEnd=event.getY();
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()) {
case R.id.tools:
ll.setVisibility(LinearLayout.VISIBLE);
return true;
case R.id.import_pics:
getPhotos();
return true;
case R.id.save:
{
Bitmap bitmap = Bitmap.createBitmap(theView.getWidth(),theView.getHeight,Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
theView.draw(canvas);
storeImage(bitmap);
bitmap.recycle();
}
return true;
case R.id.trash:
return true;
}
return false;
}