绘制一个图像android的文本中间

我必须在地图视图上放置标记,并在标记上写上一个数字。 我已经这样做了,但文本对齐方式因不同的分辨率而异。 波纹管是参考代码

float xVal = (float) curScreenCoords.x; // Point curScreenCoords float yVal = (float) curScreenCoords.y-20; // Point curScreenCoords Bitmap bitmap = BitmapFactory.decodeResource ( context.getResources() , ( R.drawable.pin_number ) ) ; canvas.drawBitmap(bitmap, xVal, yVal, getInnerPaint()); public Paint getInnerPaint() { if (innerPaint == null) { innerPaint = new Paint(); } innerPaint.setARGB(255, 117, 161, 220); // blue innerPaint.setAntiAlias(true); innerPaint.setStyle(Style.FILL); return innerPaint; } canvas.drawText(String.valueOf(10), xVal+20, yVal+22, getCountPaint()); // 10 is just for example, it can vary to one digit to two to three public Paint getCountPaint() { if (innerPaint == null) { innerPaint = new Paint(); } innerPaint.setARGB(255, 255, 255, 255); innerPaint.setAntiAlias(true); innerPaint.setStyle(Style.FILL); innerPaint.setTextSize(12f); innerPaint.setTextAlign(Align.CENTER); return innerPaint; } 

一切工作正常,除文本对齐,此代码工作正常480 * 800分辨率。 文字在画布中完美居中对齐。 x,y位置在图像上是完美的,但在320 * 480上看起来并不完美。 文本的x和y位置在此分辨率上看起来不同。 任何人都可以请建议我究竟发生了什么错误? 在不同尺寸的设备上做同样的事情有什么基础? 提前致谢。

您的值curScreenCoords.y-20xVal+20, yVal+22对于所有分辨率具有不变的像素偏移量,但是它们应取决于设备的像素密度,如下所示:

 xOffset = (int) (13.33f * context.getResources().getDisplayMetrics().density + 0.5f); yOffset = (int) (14.67f * context.getResources().getDisplayMetrics().density + 0.5f); canvas.drawText(String.valueOf(10), xVal + xOffset, yVal + yOffset, getCountPaint()); 

我认为你可以测量文字在画布上写下来的宽度和高度,然后用它来居中。 就像是:

 String text = "whatever"; Rect bounds = new Rect(); paint.getTextBounds(text, 0, text.length(), bounds); canvas.drawText(text, (canvas.getWidth() - bounds.width()) / 2, (canvas.getHeight() - bounds.height()) / 2, paint); 

嗨,我猜想上面给出的答案都不够好,所以我张贴我的答案试一试人会在所有设备上工作,并不复杂

 Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); //paint.setTextAlign(Align.CENTER); paint.setColor(activity.getResources().getColor(R.color.white)); paint.setTextSize(30); // draw text to the Canvas center Rect boundsText = new Rect(); paint.getTextBounds(String.valueOf(cluster.getMarkerList().size()), 0, String.valueOf(cluster.getMarkerList().size()).length(), boundsText); int x = (bitmap.getWidth() - boundsText.width()) / 2; int y = (bitmap.getHeight() + boundsText.height()) / 2; canvas.drawText(String.valueOf(cluster.getMarkerList().size()), x, y, paint); 

确保你检查硬件加速是关闭的。 在4.1.2和其他设备(三星Galaxy Tag 2.0),你会得到一个致命的信号11错误。

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { setLayerType(View.LAYER_TYPE_SOFTWARE, null); } 

这纠正了我用这个代码所遇到的问题。 canvas.drawText导致错误。

你可以扩展Image类并覆盖它的onDraw。 如下

 import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.Paint; import android.widget.ImageView; /** * @author amit * */ public class CustomImageView extends ImageView { private int notificationCount; private Paint paint; /** * @param context */ public CustomImageView(Context context) { super(context); notificationCount = 0; paint = new Paint(); paint.setColor(Color.RED); ColorFilter cf = new ColorFilter(); paint.setColorFilter(cf); paint.setStyle(Paint.Style.FILL); paint.setFakeBoldText(true); paint.setTextSize(15); } public synchronized void incrementNotification() { notificationCount--; this.invalidate(); } public synchronized void decrementNotification() { notificationCount++; this.invalidate(); } /** * @return the notificationCount */ public synchronized int getNotificationCount() { return notificationCount; } /** * @param notificationCount * the notificationCount to set */ public synchronized void setNotificationCount(int notificationCount) { this.notificationCount = notificationCount; this.invalidate(); } /* * (non-Javadoc) * * @see android.widget.ImageView#onDraw(android.graphics.Canvas) */ @Override protected void onDraw(Canvas canvas) { // System.out.println("OnDraw is called"); super.onDraw(canvas); if (notificationCount == 0) { return; } canvas.drawText(String.valueOf(notificationCount), 0, 0, paint); } } 

你可以调用以下任何一种方法

 incrementNotification(); decrementNotification(); setNotification(int number); 

在构造函数里选择你选择的颜色。祝你好运!

我遇到过同样的问题。 我想在位图中绘制文本 – 在Google地图上进行聚类。 实际上它在位图的CENTER上绘制文本。

代码写在Kotlin

 fun createCircleBitmapWithTextInside(context: Context, @DrawableRes drawableId: Int, text: String = "POI"): Bitmap{ val scale = context.resources.displayMetrics.density var bitmap = getBitmap(context, drawableId)//BitmapFactory.decodeResource(res, drawableId) var bitmapConfig = bitmap.config ?: Bitmap.Config.ARGB_8888 // resource bitmaps are imutable, // so we need to convert it to mutable one bitmap = bitmap.copy(bitmapConfig, true) val canvas = Canvas(bitmap) val paint = Paint(ANTI_ALIAS_FLAG) paint.color = ResourceUtils.getColor(context, R.color.white) paint.textSize = (18 * scale) paint.setShadowLayer(1f, 0f, 1f, Color.WHITE) paint.style = Paint.Style.FILL paint.textAlign = Paint.Align.CENTER val bound = Rect() paint.getTextBounds(text, 0, text.length, bound) val x = (canvas.width.toFloat() /2) // x - point to the center of width val y = canvas.height / 2 - (paint.descent() + paint.ascent()) / 2 /* Timber.d("bitmap.width:${canvas.width} \tbound.width:${bound.width()} \tx:$x") Timber.d("bitmap.height:${canvas.height} \tbound.height:${bound.height()} \ty:$y")*/ canvas.drawText(text, x, y, paint) return bitmap }