I am working On Google map in android and Image not displayed when i set in My customView Below in function createCustomMarker().Please recommend me if doing some wrong. But I set the drawable from drawable folder then displayed But not from String url.
override fun onMapReady(googleMap: GoogleMap?) {
mMap = googleMap
mMap?.animateCamera(CameraUpdateFactory.zoomTo(16.0f))
mMap?.mapType = GoogleMap.MAP_TYPE_NORMAL
mMap?.setMinZoomPreference(6.0f)
mMap?.setMaxZoomPreference(21.0f)
mMap?.isIndoorEnabled = false
mMap?.isMyLocationEnabled = true
val coordinate =
LatLng(prefs?.current_lati?.toDouble()!!, prefs?.current_longi?.toDouble()!!) //Store these lat lng values somewhere. These should be constant.
val location = CameraUpdateFactory.newLatLngZoom(
coordinate, 15f
)
for(i in 0..arraylist?.size){
var lat=arraylist?.get(i)?.latitude
var longi=arraylist?.get(i)?.longitude
mMap!!.addMarker(MarkerOptions().position(LatLng(lat!!,longi!!)).icon(BitmapDescriptorFactory.fromBitmap(createCustomMarker( requireContext(),arraylist?.get(i)!!.image))))}
mMap!!.moveCamera(CameraUpdateFactory.newLatLng(locationArrayList!![i]))
mMap!!.animateCamera(location)
}
private fun createCustomMarker(context: Context, userImage: String): Bitmap {
val marker: View =
(context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater).inflate(
R.layout.lay_cutom_marker,
null
)
val markerImage: ImageView = marker.findViewById(R.id.img_res)
var bmp: Bitmap? = null
// val url = URL(userImage)
Glide.with(context).load(userImage)
.placeholder(R.drawable.ic_user).error(R.drawable.ic_user).into(markerImage)
val displayMetrics = DisplayMetrics()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
context.display?.getRealMetrics(displayMetrics)
} else {
requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics)
}
marker.layoutParams = ViewGroup.LayoutParams(52, ViewGroup.LayoutParams.WRAP_CONTENT)
marker.measure(displayMetrics.widthPixels, displayMetrics.heightPixels)
marker.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels)
marker.buildDrawingCache()
bmp = Bitmap.createBitmap(
marker.measuredWidth, marker.measuredHeight,
Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bmp)
marker.draw(canvas)
return bmp
}
Maybe it is because of you make icon after that image is loading in drawable as you load an image. you need to increase wait time until image has been loaded after that do all stuff regarding iconGenerator.
Related
I have managed to export my recyclerview in a PDF file but I am realizing that the image that is as a header is not showing in the pdf, I only know the questions and the answers that are the check boxes
I have tried the following code to show the recyclerview in pdf.
This is my activity
`
fun getScreenshotFromRecyclerView(view: RecyclerView): Bitmap? {
val adapter = view.adapter
var bigBitmap: Bitmap? = null
if (adapter != null) {
val size = listado2.size
var height = 0
val paint = Paint()
var iHeight = 0
val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt()
// Use 1/8th of the available memory for this memory cache.
val cacheSize = maxMemory / 8
val bitmaCache =
LruCache<String, Bitmap>(cacheSize)
for (i in 0 until size) {
val holder =
adapter.createViewHolder(view, adapter.getItemViewType(i))
adapter.onBindViewHolder(holder, i)
holder.itemView.measure(
View.MeasureSpec.makeMeasureSpec(
view.width,
View.MeasureSpec.EXACTLY
),
View.MeasureSpec.makeMeasureSpec(
0,
View.MeasureSpec.UNSPECIFIED
)
)
holder.itemView.layout(
0,
0,
holder.itemView.measuredWidth,
holder.itemView.measuredHeight
)
holder.itemView.isDrawingCacheEnabled = true
holder.itemView.buildDrawingCache()
val drawingCache = holder.itemView.drawingCache
if (drawingCache != null) {
bitmaCache.put(i.toString(), drawingCache)
}
// holder.itemView.setDrawingCacheEnabled(false);
// holder.itemView.destroyDrawingCache();
height += holder.itemView.measuredHeight
}
bigBitmap =
Bitmap.createBitmap(view.measuredWidth, height, Bitmap.Config.ARGB_8888)
val bigCanvas = Canvas(bigBitmap)
bigCanvas.drawColor(Color.WHITE)
for (i in 0 until size) {
val bitmap = bitmaCache[i.toString()]
bigCanvas.drawBitmap(bitmap!!, 0f, iHeight.toFloat(), paint)
iHeight += bitmap.height
bitmap.recycle()
}
}
return bigBitmap
}
`
This is my CreateFile.kt class
`
open fun salvarPDF(bitmap: Bitmap, nombreDeArchivo : String): String?{
archivo = File(pasta, "$nombreDeArchivo.pdf")
val archivoPDF = PdfDocument()
val pageInfo: PdfDocument.PageInfo = PageInfo.Builder(bitmap.width, bitmap.height, 1).create()
val pagina : PdfDocument.Page = archivoPDF.startPage(pageInfo)
val canvas : Canvas = pagina.canvas
canvas.drawBitmap(bitmap,null, Rect(0,0,bitmap.width, bitmap.height),null)
archivoPDF.finishPage(pagina)
try {
archivo!!.createNewFile()
val streamDeSalidad: OutputStream = FileOutputStream(archivo)
archivoPDF.writeTo(streamDeSalidad)
streamDeSalidad.close()
archivoPDF.close()
}catch (e: IOException){
return "error en crear$e"
}
return "creado"
}
`
This is the result in PDF
But it should come out as follows.
Any idea where in the code I am failing.
I was doing the simple feature that I am taking the photo with Camerax and uploading the photo to Imagga to do the face detection by using this API, and here is the API result [Face(confidence=100.0, coordinates=Coordinates(height=1243, width=1243, xmax=2660, xmin=1417, ymax=3359, ymin=2116), face_id=)]
And base on the API document, the Coordinates are parameters that I needed to input to drawRect(xmin, ymin, xmax, ymax, paint), but the rectangle is always in the wrong position on the screen.
I've tried total 64 combinations of those four points but non is correct.
What have I done wrong? here's my code
take and upload photo to Imagga:
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
Log.e(TAG, "onImageSaved: " + output.savedUri)
savedUri = output.savedUri
val file = File(getPath(savedUri, applicationContext) ?: "")
val mFile = RequestBody.create(MediaType.parse("image/*"), file)
val fileToUpload = MultipartBody.Part.createFormData("image", file.name, mFile)
photoJob?.cancel()
photoJob = lifecycleScope.launch {
binding.isLoading = true
mainViewMode.startFaceDetection(fileToUpload)
}
}
fun getPath(contentUri: Uri?, context: Context): String? {
var res: String? = null
val proj = arrayOf(MediaStore.Images.Media.DATA)
val cursor: Cursor = context.contentResolver.query(contentUri!!, proj, null, null, null)!!
if (cursor.moveToFirst()) {
val index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
res = cursor.getString(index)
}
cursor.close()
return res
}
receive face detection results from Imagga:
mainViewMode.apply {
faceResult.observe(this#MainActivity) {
showDetectionResult(it, savedUri)
}
}
private fun showDetectionResult(it: FaceDetectionResp, savedUri: Uri?) {
Log.e(TAG, "startFaceDetection: ${it.result.faces}")
val originBitmap = MediaStore.Images.Media.getBitmap(contentResolver, savedUri)
val bmp = originBitmap!!.copy(originBitmap.config, true)
val canvas = Canvas(bmp)
val paint = Paint().apply {
color = Color.GREEN
style = Paint.Style.STROKE
strokeWidth = 5f
}
val left = it.result.faces[0].coordinates.xmin.toFloat()
val top = it.result.faces[0].coordinates.ymin.toFloat()
val right = it.result.faces[0].coordinates.xmax.toFloat()
val bottom = it.result.faces[0].coordinates.ymax.toFloat()
// it did draw the rectangle but never in the right position that I expected
canvas.drawRect(left, top, right, bottom, paint)
//because I got landscape photo, so I rotate the bitmap to portrait
binding.ivFace.setImageBitmap(rotateImage(bmp, -90f))
}
fun rotateImage(source: Bitmap, angle: Float): Bitmap? {
val matrix = Matrix()
matrix.postRotate(angle)
return Bitmap.createBitmap(
source, 0, 0, source.width, source.height,
matrix, true
)
}
I've been stuck in this for a week, can anyone help me?
The problem
If I use the following helper / extension I will get an exception IBitmapDescriptorFactory is not initialized.
I checked Stackoverflow, some of them recommend to create a local property of the factory and than assign it but this does also not work.
Android Studio shows me the icon on the right side, because of this I think the asset has been added correctly.
Source
fun Webcam.toMarkerOptions(): MarkerOptions {
return MarkerOptions()
.title(name)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_map_webcam))
.position(coordinate.toLngLat())
}
Source 2 which also crashes
fun MarkerOptions.icon(context: Context, #DrawableRes vectorDrawable: Int): MarkerOptions {
this.icon(ContextCompat.getDrawable(context, vectorDrawable)?.run {
setBounds(0, 0, intrinsicWidth, intrinsicHeight)
val bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888)
draw(Canvas(bitmap))
BitmapDescriptorFactory.fromBitmap(bitmap)
})
return this
}
I have created the MapMarker composable method for this which takes resourceId:
#Composable
fun MapMarker(
context: Context,
position: LatLng,
title: String,
snippet: String,
#DrawableRes iconResourceId: Int
) {
val icon = bitmapDescriptor(
context, iconResourceId
)
Marker(
position = position,
title = title,
snippet = snippet,
icon = icon,
)
}
where bitmapDescriptor:
fun bitmapDescriptor(
context: Context,
vectorResId: Int
): BitmapDescriptor? {
// retrieve the actual drawable
val drawable = ContextCompat.getDrawable(context, vectorResId) ?: return null
drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
val bm = Bitmap.createBitmap(
drawable.intrinsicWidth,
drawable.intrinsicHeight,
Bitmap.Config.ARGB_8888
)
// draw it onto the bitmap
val canvas = android.graphics.Canvas(bm)
drawable.draw(canvas)
return BitmapDescriptorFactory.fromBitmap(bm)
}
For more details: https://erselankhan.medium.com/jetpack-compose-custom-google-map-marker-erselan-khan-e6e04178a30b
I'm using mapbox-sdk android for location tracking. I want to add few custom markers to the map in specified location. But the below code doesn't works for me.
MarkerOptions options = new MarkerOptions();
options.title("pos");
IconFactory iconFactory = IconFactory.getInstance(MainActivity.this);
Icon icon = iconFactory.fromResource(R.drawable.home);
options.icon(icon);
options.position(new LatLng(80.27, 13.09));
mapboxMap.addMarker(options);
I use mapox-sdk:6.0.1
use this:
private fun addMarkerIconsToMap(loadedMapStyle: Style) {
BitmapUtils.getBitmapFromDrawable(getDrawable(R.drawable.red_marker))?.let {
loadedMapStyle.addImage("icon-id", it)
}
if(!locationList.isNullOrEmpty()){
val feature: ArrayList<Feature> = ArrayList()
for (x in 0 until locationList.size){
feature.add(Feature.fromGeometry(Point.fromLngLat(locationList[x].long, locationList[x].lat)))
}
loadedMapStyle.addSource(GeoJsonSource("source-id",
FeatureCollection.fromFeatures(feature)
)
)
loadedMapStyle.addLayer(SymbolLayer("layer-id", "source-id").withProperties(
iconImage("icon-id"),
iconOffset(arrayOf(0f, -8f))
)
)
}
}
inside locationList is Array of long: Double and lat: Double
YourActivity :
class YourActivity : AppCompatActivity(), OnMapReadyCallback {
private lateinit var mapboxMap: MapboxMap
...
}
and then override :
override fun onMapReady(mapboxMap: MapboxMap) {
mapboxMap.setStyle(Style.MAPBOX_STREETS){
addMarkerIconsToMap(it)
}
this.mapboxMap = mapboxMap
}
This is how I would add a custom marker (from a Compose perspective).
(You can either do it from the viewModel depending on your program structure)
AndroidView(
factory = { mapView }, modifier = Modifier.fillMaxWidth()
) { mView ->
val bitmap = bitmapFromDrawableRes(context, R.drawable.chicken_marker)!!
val annotation = mView.annotations
val pointManager = annotation.createPointAnnotationManager()
list.forEach { point ->
val pointOptions = PointAnnotationOptions()
.withPoint(point)
.withIconImage(bitmap)
pointManager.create(pointOptions.apply { iconSize = 0.8 })
}
Here's the functions used to get the drawable(".svg",".png",".jpeg")
private fun bitmapFromDrawableRes(context: Context, #DrawableRes resourceId: Int): Bitmap? =
convertDrawableToBitmap(AppCompatResources.getDrawable(context, resourceId))
private fun convertDrawableToBitmap(sourceDrawable: Drawable?): Bitmap? {
if (sourceDrawable == null) {
return null
}
return if (sourceDrawable is BitmapDrawable) {
sourceDrawable.bitmap
} else {
// copying drawable object to not manipulate on the same reference
val constantState = sourceDrawable.constantState ?: return null
val drawable = constantState.newDrawable().mutate()
val bitmap: Bitmap = Bitmap.createBitmap(
drawable.intrinsicWidth, drawable.intrinsicHeight,
Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
bitmap
}
}
I want to set image on marker. Image is stored in firerebase storage and I have download link of image. Now How can I set that image on marker
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
reference = reference.child("Profile");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds:dataSnapshot.getChildren()){
latitude = (Double) ds.child("Latitude").getValue();
longitude = (Double) ds.child("Longitude").getValue();
String name=(String) ds.child("Name").getValue();
String imgUrl = (String) ds.child("imageURL").getValue();//Here is image Url of marker
LatLng latLng = new LatLng(latitude,longitude);
mMap.addMarker(new MarkerOptions().position(latLng).title(name));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 10));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
After too much research I found a way, but you will need Glide to work. This code is in Kotlin.
Once you have the url with the image in storage firebase. Call Glide this way to transform the url link in a bitmap. Thanks to glide this is easy:
var bitmapFinal : Bitmap?
Glide.with(this)
.asBitmap()
.load(link)
.into(object : CustomTarget<Bitmap>(){
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
bitmapFinal = createUserBitmapFinal(resource) //here we will insert the bitmap we got with the link in a placehold with white border.
val mark1 = mMap.addMarker(MarkerOptions().position(latLng).title("Você está aqui").icon(BitmapDescriptorFactory.fromBitmap(bitmapFinal)))
mark1.tag=0
mMap.setOnMarkerClickListener (this#MapsActivity)
}
override fun onLoadCleared(placeholder: Drawable?) {
// this is called when imageView is cleared on lifecycle call or for
// some other reason.
// if you are referencing the bitmap somewhere else too other than this imageView
// clear it here as you can no longer have the bitmap
}
})
At this point, you could insert the bitmap (resource) directly in marker, just tweeking the code above. But if you want to use a placeholder with a white border of any other thing, use this code, whereas bitmapInicial is the bitmap you just get in Glide above:
private fun createUserBitmapFinal(bitmapInicial: Bitmap?): Bitmap? {
var result: Bitmap? = null
try {
result = Bitmap.createBitmap(dp(62f), dp(76f), Bitmap.Config.ARGB_8888) //change the size of the placeholder
result.eraseColor(Color.TRANSPARENT)
val canvas = Canvas(result)
val drawable: Drawable = resources.getDrawable(R.drawable.placeholder)
drawable.setBounds(0, 0, dp(62f), dp(76f)) //change the size of the placeholder, but you need to maintain the same proportion of the first line
drawable.draw(canvas)
val roundPaint = Paint(Paint.ANTI_ALIAS_FLAG)
val bitmapRect = RectF()
canvas.save()
if (bitmapInicial != null) {
val shader =
BitmapShader(bitmapInicial, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
val matrix = Matrix()
val scale: Float = dp(104f) / bitmapInicial.width.toFloat() //reduce or augment here change the size of the original bitmap inside the placehoder. But you need to adjust the line bitmapRect with the same proportion
matrix.postTranslate(5f, 5f)
matrix.postScale(scale, scale)
roundPaint.shader = shader
shader.setLocalMatrix(matrix)
bitmapRect[10f, 10f, 104f+10f]=104f+10f //change here too to change the size
canvas.drawRoundRect(bitmapRect, 56f, 56f, roundPaint)
}
canvas.restore()
try {
canvas.setBitmap(null)
} catch (e: java.lang.Exception) {
}
} catch (t: Throwable) {
t.printStackTrace()
}
return result
}
fun dp(value: Float): Int {
return if (value == 0f) {
0
} else Math.ceil(resources.displayMetrics.density * value.toDouble()).toInt()
}
fonts:
How does one use glide to download an image into a bitmap?