【问题标题】:How do I write text over a picture in Android and save it?如何在 Android 中的图片上写文字并保存?
【发布时间】:2016-09-19 21:52:23
【问题描述】:

如何在图像上写文字然后将其保存在 Android 中?

基本上我想让用户在我的相机应用程序将点击的图像上写一些东西。我可以在相机预览中使用 onDraw 方法编写并向他们展示。但是在用户点击图片后,我想在图片上写上文字然后保存。

【问题讨论】:

    标签: android


    【解决方案1】:

    你可以把一个EditText写进去,写完之后,你先把它转换成Bitmap,比如:

    Bitmap bmp = Bitmap.createBitmap(mEditText.getDrawingCache());
    

    现在您可以像这样将创建的图像 bmp 添加到原始图像:

    电话:Bitmap combined = combineImages(bgBitmap,bmp);

    public Bitmap combineImages(Bitmap background, Bitmap foreground) { 
    
            int width = 0, height = 0;
            Bitmap cs;
    
            width = getWindowManager().getDefaultDisplay().getWidth();
            height = getWindowManager().getDefaultDisplay().getHeight();
    
            cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            Canvas comboImage = new Canvas(cs);
            background = Bitmap.createScaledBitmap(background, width, height, true);
            comboImage.drawBitmap(background, 0, 0, null);
            comboImage.drawBitmap(foreground, matrix, null);
    
            return cs;
        }
    

    【讨论】:

    • 天才,我永远不会有那样的。加油!
    • 如果我们将textview(前景)动态放在一个视图上(宽度和高度小于Sd中的原始图像),然后使用原始图像'背景'(背景=位图......),添加文字位置改变。如何保持位置?!
    • 矩阵值应该是多少?
    • 确保设置editText.setDrawingCacheEnabled(true) 否则editText.getDrawingCache() 始终为null
    • 矩阵是绘制前景的起点,可以用0,0代替矩阵
    【解决方案2】:

    您必须实现一个允许用户在其上绘图的画布,然后将该画布的背景设置为该特定图像。这只是一个猜测,但它在某个地方。

    【讨论】:

      【解决方案3】:

      让我们帮助你.. 首先,您必须使用画布进行绘图。创建一个扩展 ImageView 的自定义视图。这是onDraw函数的帮助代码..:

          @Override
          public void onDraw(Canvas canvas) {
              super.onDraw(canvas);
              mIcon.setBounds(0, 0, mIcon.getMinimumWidth(),
                      mIcon.getMinimumHeight());
      
              canvas.translate(mPosX, mPosY);
              canvas.scale(mScaleFactor, mScaleFactor, canvas.getWidth() * 0.5f,
                      canvas.getWidth() * 0.5f);
              mIcon.draw(canvas);
      
              rect = canvas.getClipBounds();
      
              for (Path path : listPath) {
                  canvas.drawPath(path, paint);
      
              }
      
          }
      

      现在是 onTouch:

          @Override
          public boolean onTouchEvent(MotionEvent ev) {
              // Let the ScaleGestureDetector inspect all events.
              mScaleDetector.onTouchEvent(ev);
      
              final int action = ev.getAction();
              switch (action & MotionEvent.ACTION_MASK) {
              case MotionEvent.ACTION_DOWN: {
      
                  if (drawing) {
      
                      startPoint = new Point((int) ev.getX(), (int) ev.getY());
                      path = new Path();
                      float x = ev.getX() / mScaleFactor + rect.left;
                      float y = ev.getY() / mScaleFactor + rect.top;
                      path.moveTo(x, y);
                      path.lineTo(x, y);
      
                      mLastTouchX_1 = x;
                      mLastTouchY_1 = y;
                  }
      
                  else {
                      final float x = ev.getX();
                      final float y = ev.getY();
      
                      mLastTouchX = x;
                      mLastTouchY = y;
                      mActivePointerId = ev.getPointerId(0);
                  }
                  break;
              }
      
              case MotionEvent.ACTION_MOVE: {
      
                  if (drawing) {
      
                      float x = ev.getX() / mScaleFactor + rect.left;
                      float y = ev.getY() / mScaleFactor + rect.top;
      
                      path.moveTo(mLastTouchX_1, mLastTouchY_1);
                      path.lineTo(x, y);
      
                      mLastTouchX_1 = x;
                      mLastTouchY_1 = y;
                  }
      
                  else {
                      final int pointerIndex = ev
                              .findPointerIndex(mActivePointerId);
                      final float x = ev.getX(pointerIndex);
                      final float y = ev.getY(pointerIndex);
      
                      // Only move if the ScaleGestureDetector isn't processing a
                      // gesture.
                      if (!mScaleDetector.isInProgress()) {
                          final float dx = x - mLastTouchX;
                          final float dy = y - mLastTouchY;
      
                          mPosX += dx;
                          mPosY += dy;
      
                          invalidate();
                      }
      
                      mLastTouchX = x;
                      mLastTouchY = y;
                  }
                  break;
              }
      
              case MotionEvent.ACTION_UP: {
                  path_helper_1 = new Path();
                  path_helper_2 = new Path();
      
                  endPoint = new Point((int) ev.getX(), (int) ev.getY());
      
                  int left, top, right, bottom;
      
      
      
                  left = endPoint.x - 10;
                  top = endPoint.y - 10;
      
                  right = endPoint.x + ((endPoint.y / 2));
                  bottom = endPoint.x + ((endPoint.y / 2));
      
      
      
                  float dx, dy;
                  dx = endPoint.x - startPoint.x;
                  dy = endPoint.y - startPoint.y;
      
                  dx = dx * -1;
                  dy = dy * -1;
      
                  // dx = dy = 100;
      
                  double cos = 0.866 * .1;
                  double sin = 0.500 * .1;
      
                  PointF end1 = new PointF((float) (endPoint.x + (dx * cos + dy
                          * -sin)), (float) (endPoint.y + (dx * sin + dy * cos)));
                  PointF end2 = new PointF((float) (endPoint.x + (dx * cos + dy
                          * sin)), (float) (endPoint.y + (dx * -sin + dy * cos)));
      
                  // path.moveTo(endPoint.x, endPoint.y);
                  //
                  // path.lineTo(endPoint.x, endPoint.y);
                  //
                  // path.lineTo(end1.x, end1.y);
                  //
                  // path.moveTo(endPoint.x, endPoint.y);
                  //
                  // path.lineTo(end2.x, end2.y);
                  //
                  //
                  // listPath.add(path);
      
                  mActivePointerId = INVALID_POINTER_ID;
                  break;
              }
      
              case MotionEvent.ACTION_CANCEL: {
                  mActivePointerId = INVALID_POINTER_ID;
                  break;
              }
      
              case MotionEvent.ACTION_POINTER_UP: {
                  final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
                  final int pointerId = ev.getPointerId(pointerIndex);
                  if (pointerId == mActivePointerId) {
                      // This was our active pointer going up. Choose a new
                      // active pointer and adjust accordingly.
                      final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                      mLastTouchX = ev.getX(newPointerIndex);
                      mLastTouchY = ev.getY(newPointerIndex);
                      mActivePointerId = ev.getPointerId(newPointerIndex);
                  }
                  break;
              }
              }
              invalidate();
      
              return true;
          }
      

      如果你想实现这样的缩放功能,也可以创建一个私有类:

          private class ScaleListener extends
                  ScaleGestureDetector.SimpleOnScaleGestureListener {
              @Override
              public boolean onScale(ScaleGestureDetector detector) {
      
                  if (zoom) {
                      mScaleFactor *= detector.getScaleFactor();
      
                      // Don't let the object get too small or too large.
                      mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));
                  }
                  invalidate();
                  return true;
              }
          }
      }
      

      从上面的代码中汲取灵感并根据您的要求进行更改。 注意 上面的代码实现了绘图和缩放功能。如果你想在图像上添加文本,那么就像路径绘图一样,你也可以使用 canvas.drawText 在画布上绘制文本。如果您想要多个文本覆盖图像,请创建一个数组列表。

      【讨论】:

        【解决方案4】:

        在位图上添加文字:

        public Bitmap drawTextToBitmap(Context gContext, 
          int gResId, 
          String gText) {
          Resources resources = gContext.getResources();
          float scale = resources.getDisplayMetrics().density;
          Bitmap bitmap = 
              BitmapFactory.decodeResource(resources, gResId);
        
          android.graphics.Bitmap.Config bitmapConfig =
              bitmap.getConfig();
          // set default bitmap config if none
          if(bitmapConfig == null) {
            bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
          }
          // resource bitmaps are imutable, 
          // so we need to convert it to mutable one
          bitmap = bitmap.copy(bitmapConfig, true);
        
          Canvas canvas = new Canvas(bitmap);
          // new antialised Paint
          Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
          // text color - #3D3D3D
          paint.setColor(Color.rgb(61, 61, 61));
          // text size in pixels
          paint.setTextSize((int) (14 * scale));
          // text shadow
          paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);
        
          // draw text to the Canvas center
          Rect bounds = new Rect();
          paint.getTextBounds(gText, 0, gText.length(), bounds);
          int x = (bitmap.getWidth() - bounds.width())/2;
          int y = (bitmap.getHeight() + bounds.height())/2;
        
          canvas.drawText(gText, x, y, paint);
        
          return bitmap;
        }
        

        来源:http://www.skoumal.net/en/android-how-draw-text-bitmap/

        在位图上添加多行文字:

        public Bitmap drawMultilineTextToBitmap(Context gContext,
                                           int gResId,
                                           String gText) {
        
          // prepare canvas
          Resources resources = gContext.getResources();
          float scale = resources.getDisplayMetrics().density;
          Bitmap bitmap = BitmapFactory.decodeResource(resources, gResId);
        
          android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
          // set default bitmap config if none
          if(bitmapConfig == null) {
            bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
          }
          // resource bitmaps are imutable,
          // so we need to convert it to mutable one
          bitmap = bitmap.copy(bitmapConfig, true);
        
          Canvas canvas = new Canvas(bitmap);
        
          // new antialiased Paint
          TextPaint paint=new TextPaint(Paint.ANTI_ALIAS_FLAG);
          // text color - #3D3D3D
          paint.setColor(Color.rgb(61, 61, 61));
          // text size in pixels
          paint.setTextSize((int) (14 * scale));
          // text shadow
          paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);
        
          // set text width to canvas width minus 16dp padding
          int textWidth = canvas.getWidth() - (int) (16 * scale);
        
          // init StaticLayout for text
          StaticLayout textLayout = new StaticLayout(
            gText, paint, textWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
        
          // get height of multiline text
          int textHeight = textLayout.getHeight();
        
          // get position of text's top left corner
          float x = (bitmap.getWidth() - textWidth)/2;
          float y = (bitmap.getHeight() - textHeight)/2;
        
          // draw text to the Canvas center
          canvas.save();
          canvas.translate(x, y);
          textLayout.draw(canvas);
          canvas.restore();
        
          return bitmap;
        }
        

        来源:http://www.skoumal.net/en/android-drawing-multiline-text-on-bitmap/

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-10
          • 2010-10-25
          • 1970-01-01
          • 2012-02-19
          • 1970-01-01
          相关资源
          最近更新 更多