将MapView保存为位图

时间:2011-06-02 22:26:55

标签: android google-maps bitmap

我已经尝试了两种方法将MapView保存为我在这里找到的位图,似乎没有一种方法适合我。第一个选项,

Bitmap bitMap = mMapView.getDrawingCache();             
mMapView.setDrawingCacheEnabled(true);
bitMap = mMapView.getDrawingCache(true);

和第二个,

Canvas offscreencanvas = new Canvas();
Bitmap bmap = Bitmap.createBitmap(mMapView.getWidth(), mMapView.getHeight(),
                    Bitmap.Config.ARGB_8888);
bmap.copy(Config.ARGB_4444, true);
offscreencanvas.setBitmap(bmap);
offscreencanvas.drawBitmap(bmap, 0, 0, null);

两者都会产生宽度和高度为-1的位图对象,所以当我尝试使用位图作为纹理时,它不会显示。在mapview渲染后,我会在按钮单击中调用位图保存代码,但它仍会提供相同的结果。

有人设法做到了吗?

3 个答案:

答案 0 :(得分:2)

我在尝试使用绘图缓存时遇到了类似的问题。我找到的一些项目帮助了我:

  • 确保立即复制图形缓存。 Android可以并且将回收缓存绘制的位图。当我用它绘制视图时,我已经让Android破坏了位图缓存。
  • 出于某种原因,在检索缓存之前销毁缓存会给我更一致的结果。

以下是我正在使用的工作代码:

// Disable caching, destroy the cache, and force a rebuild
imageView.setWillNotCacheDrawing(false);
imageView.destroyDrawingCache();
imageView.buildDrawingCache();

// Copy the drawing cache before the system recycles it
Bitmap cachedImage = Bitmap.createBitmap(imageView.getDrawingCache());

另请注意,我使用的是ImageView,但我希望MapView的代码路径相同。

最后,在您发布的代码示例中,您将创建一个与地图视图大小相同的位图。您复制此位图,然后将结果抛出。然后将画布设置为由此位图支持,然后尝试将位图绘制到位图。 (是的,我输入正确。)尝试这样的事情,代替你的画布代码

Bitmap mapCache = /* Get this using the previous code */
Bitmap bmap = Bitmap.createBitmap(mMapView.getWidth(), mMapView.getHeight(),
                        Bitmap.Config.ARGB_8888);
Canvas offscreencanvas = new Canvas(bmap);
offscreencanvas.drawBitmap(mapCache, 0, 0, null);

答案 1 :(得分:1)

我没有使用MapView,我假设它扩展了View类,因此,确保在构建cach之前指定布局,你应该按照以下步骤进行:

我就是这样做的,你可以改变它,或尝试不同的东西,如果你喜欢:

View v = new View(context)
{   public void onMeasure(int w, int h)
    {  setMeasuredDimension(width, height);//the desired width and height
    }}; //important
v.setDrawingCacheEnabled(true); //important
v.measure(width,height); //important the desired width and height
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); //important
v.setDrawingCacheQuality(DRAWING_CACHE_QUALITY_HIGH);
v.setLayoutParams(new LayoutParams(width,height)); //important
v.buildDrawingCache(true); //important
Bitmap b = v.getDrawingCache(true);
v.buildDrawingCache(false);

希望这有帮助, 最好的问候。

答案 2 :(得分:0)

无需将mapview绘图缓存保存为位图。这将很快被Android清除,因此您必须在mapView上放置一个布局并从中获取drawingcache位图。 这个类是我用来在叠加上定位一个点并在imageview上获取地图的图像。

import java.io.IOException;
import java.util.List;
import java.util.Locale;
import android.R.layout;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

public class GoogleMap extends MapActivity {

    MapView mapView; 
    MapController mc;
    GeoPoint p;
    LinearLayout layout;
    ImageView imageview;

    /** Called when the activity is first created. */
    @SuppressWarnings("deprecation")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.testmap);
          layout   = (LinearLayout)findViewById(R.id.maplayout);
        layout.setDrawingCacheEnabled(true);
        layout.setDrawingCacheQuality(LinearLayout.DRAWING_CACHE_QUALITY_HIGH);
        imageview=(ImageView)findViewById(R.id.imageView);
        ViewTreeObserver vto = layout.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

         public void onGlobalLayout() {
          layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
          getDrawingBitmap();
         }
        });
        mapView = (MapView) findViewById(R.id.mapview);
        mapView.setStreetView(true);
        mapView.setBuiltInZoomControls(true);
        /*LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom);  
        View zoomView = mapView.getZoomControls(); 

        zoomLayout.addView(zoomView, 
            new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, 
                LayoutParams.WRAP_CONTENT));*/ 
        mapView.displayZoomControls(true);

        mc = mapView.getController();
        String coordinates[] = {"23.0504926", "72.528938925"};
        double lat = Double.parseDouble(coordinates[0]);
        double lng = Double.parseDouble(coordinates[1]);

        p = new GeoPoint(
            (int) (lat * 1E6), 
            (int) (lng * 1E6));


        mc.animateTo(p);
        mc.setZoom(17); 

        //---Add a location marker---
        MapOverlay mapOverlay = new MapOverlay();
        List<Overlay> listOfOverlays = mapView.getOverlays();
        listOfOverlays.clear();
        listOfOverlays.add(mapOverlay);        

        mapView.invalidate();
    }
    public void getDrawingBitmap(){
         Bitmap b = layout.getDrawingCache();
         imageview.setImageBitmap(b);
    }

    public void fitAgain(GeoPoint point){
        p = point;


            mc.animateTo(p,new Runnable() {

                public void run() {
                     getDrawingBitmap();

                }
            });
          //  mc.setZoom(17); 
        MapOverlay mapOverlay = new MapOverlay();
        List<Overlay> listOfOverlays = mapView.getOverlays();
        listOfOverlays.clear();
        listOfOverlays.add(mapOverlay);
        mapView.invalidate();

        System.out.println("");
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }

    class MapOverlay extends com.google.android.maps.Overlay
    {
        @Override
        public boolean draw(Canvas canvas, MapView mapView, 
        boolean shadow, long when) 
        {
            super.draw(canvas, mapView, shadow);                   

            //---translate the GeoPoint to screen pixels---
            Point screenPts = new Point();
            mapView.getProjection().toPixels(p, screenPts);

            //---add the marker---
            Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_maps_indicator_current_position);            
            canvas.drawBitmap(bmp, screenPts.x-20, screenPts.y-20, null);         
            return true;
        }

        @Override
        public boolean onTouchEvent(MotionEvent event, MapView mapView) 
        {   
            //---when user lifts his finger---
            if (event.getAction() == 1) {                
                GeoPoint p = mapView.getProjection().fromPixels(
                    (int) event.getX(),
                    (int) event.getY());

                Geocoder geoCoder = new Geocoder(
                    getBaseContext(), Locale.getDefault());
                try {
                    List<Address> addresses = geoCoder.getFromLocation(
                        p.getLatitudeE6()  / 1E6, 
                        p.getLongitudeE6() / 1E6, 1);

                    String add = "";
                    if (addresses.size() > 0) 
                    {
                        for (int i=0; i<addresses.get(0).getMaxAddressLineIndex(); 
                             i++)
                           add += addresses.get(0).getAddressLine(i) + "\n";
                    }

                    Toast.makeText(getBaseContext(), add, Toast.LENGTH_SHORT).show();
                }
                catch (IOException e) {                
                    e.printStackTrace();
                } 
                fitAgain(p);
                return true;
            }
            else                
                return false;
        }        
    }
}