Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

toImage (from a map) as backgroundImage for a window

Hey there!

I have a map view within a window and a button bar underneath that map view.

One button opens a new modal window with options to manipulate the map.

What I am trying to do right now is getting the current map as an image to give that modal window a background image that looks like the map.

My Code looks like this:

  var backgroundImage = mapview.toImage;
  Titanium.API.info(backgroundImage);
  var w = Ti.UI.createWindow({
    backgroundColor:'gray'
  });
  win1.add(w);

That info returns: [INFO] [object TiMapView]

But when I change my code to this:

  var backgroundImage = mapview.toImage;
  Titanium.API.info(backgroundImage);
  var w = Ti.UI.createWindow({
    backgroundImage:backgroundImage
  });
  win1.add(w);

the simulator crashes:


2010-06-27 14:39:13.087 geoWetter[12676:207] -[TiMapViewProxy isEqualToString:]: unrecognized selector sent to instance 0x7c20040
[ERROR] The application has crashed with an unhandled exception. Stack trace:
0 CoreFoundation 0x036488fc __exceptionPreprocess + 156
1 libobjc.A.dylib 0x037965de objc_exception_throw + 47
2 CoreFoundation 0x0364a42b -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x035ba116 ___forwarding___ + 966
4 CoreFoundation 0x035b9cd2 _CF_forwarding_prep_0 + 50
5 geoWetter 0x000680ed -[TiUIView setBackgroundImage_:] + 244
6 geoWetter 0x0009b8de DoProxyDelegateReadKeyFromProxy + 265
7 geoWetter 0x0009bc69 DoProxyDelegateReadValuesWithKeysFromProxy + 801
8 geoWetter 0x000691c9 -[TiUIView readProxyValuesWithKeys:] + 53
9 geoWetter 0x00057b94 -[TiViewProxy firePropertyChanges] + 109
10 geoWetter 0x00057eb9 -[TiViewProxy view] + 507
11 geoWetter 0x000587d6 -[TiViewProxy layoutChild:] + 788
12 geoWetter 0x00055e22 -[TiViewProxy layoutChildOnMainThread:] + 130
13 geoWetter 0x00056498 -[TiViewProxy add:] + 924
14 Foundation 0x00580e9a __NSThreadPerformPerform + 251
15 CoreFoundation 0x03629d7f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
16 CoreFoundation 0x035882cb __CFRunLoopDoSources0 + 571
17 CoreFoundation 0x035877c6 __CFRunLoopRun + 470
18 CoreFoundation 0x03587280 CFRunLoopRunSpecific + 208
19 CoreFoundation 0x035871a1 CFRunLoopRunInMode + 97
20 GraphicsServices 0x04e332c8 GSEventRunModal + 217
21 GraphicsServices 0x04e3338d GSEventRun + 115
22 UIKit 0x0080fb58 UIApplicationMain + 1160
23 geoWetter 0x0000406f main + 362
24 geoWetter 0x00003021 start + 53
2010-06-27 14:39:13.091 geoWetter[12676:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TiMapViewProxy isEqualToString:]: unrecognized selector sent to instance 0x7c20040'
*** Call stack at first throw:
(
0 CoreFoundation 0x03648919 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x037965de objc_exception_throw + 47
2 CoreFoundation 0x0364a42b -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x035ba116 ___forwarding___ + 966
4 CoreFoundation 0x035b9cd2 _CF_forwarding_prep_0 + 50
5 geoWetter 0x000680ed -[TiUIView setBackgroundImage_:] + 244
6 geoWetter 0x0009b8de DoProxyDelegateReadKeyFromProxy + 265
7 geoWetter 0x0009bc69 DoProxyDelegateReadValuesWithKeysFromProxy + 801
8 geoWetter 0x000691c9 -[TiUIView readProxyValuesWithKeys:] + 53
9 geoWetter 0x00057b94 -[TiViewProxy firePropertyChanges] + 109
10 geoWetter 0x00057eb9 -[TiViewProxy view] + 507
11 geoWetter 0x000587d6 -[TiViewProxy layoutChild:] + 788
12 geoWetter 0x00055e22 -[TiViewProxy layoutChildOnMainThread:] + 130
13 geoWetter 0x00056498 -[TiViewProxy add:] + 924
14 Foundation 0x00580e9a __NSThreadPerformPerform + 251
15 CoreFoundation 0x03629d7f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
16 CoreFoundation 0x035882cb __CFRunLoopDoSources0 + 571
17 CoreFoundation 0x035877c6 __CFRunLoopRun + 470
18 CoreFoundation 0x03587280 CFRunLoopRunSpecific + 208
19 CoreFoundation 0x035871a1 CFRunLoopRunInMode + 97
20 GraphicsServices 0x04e332c8 GSEventRunModal + 217
21 GraphicsServices 0x04e3338d GSEventRun + 115
22 UIKit 0x0080fb58 UIApplicationMain + 1160
23 geoWetter 0x0000406f main + 362
24 geoWetter 0x00003021 start + 53
)
terminate called after throwing an instance of 'NSException'
[INFO] Application has exited from Simulator

How can I get this to work?

— asked June 27th 2010 by Dominik Hahn
  • iphone
  • map
  • mobile
  • sdk4
  • toimage
0 Comments

5 Answers

  • Accepted Answer

    Guys, I've found the solution. :)

    I have to create a temporary file,
    save the blob to that file and
    use the native path

    This code works:

    var theMap = mapview.toImage();
    var file = Titanium.Filesystem.createTempFile(Titanium.Filesystem.resourcesDirectory);
    Ti.API.info('size = ' + file.size);
    file.write(theMap); // this is where the magic happens!
    Ti.API.info('size = ' + file.size);
    Ti.API.info('name = ' + file.name);
    Ti.API.info('nativePath = ' + file.nativePath);
    var w = Ti.UI.createWindow({
        backgroundColor:'#fafafa',
        backgroundImage:file.nativePath
      });
    win1.add(w);
    

    Now the background image is a bit stretched but it's there. :)

    — answered June 30th 2010 by Dominik Hahn
    permalink
    2 Comments
    • You saved my life ;)

      — commented January 9th 2013 by Yann Offredi
    • I have created the view to display the map. And in the bottom of the map there is one button. When
      user click on that button it will take the screenshot / take the image of the map. It is working fine in iOS but in android it will capture black image rather then the proper image of the map.

      Find the below is my code.. Below function will display the map.

      function GetCurrentLocation(){
              Titanium.Geolocation.getCurrentPosition(function(e){
                  if (e.error){
                      alert('HFL cannot get your current location');
                      _CallBack();
                      /*mapview = Map.createView({
                          mapType: Map.SATELLITE_TYPE,
                          region: {latitude: 39.9319917, longitude: -104.8842739, latitudeDelta:0.01, longitudeDelta:0.01},
                          animate:true,
                          regionFit:true,
                          userLocation:true
                      });
                      MapsLoaded = true;
                       ContainerView.add(mapview);
                      CreateGrid();*/
                      return;
                  }
      
                  var longitude = e.coords.longitude;
                  var latitude = e.coords.latitude;
                  mapview = Map.createView({
                      mapType: Map.SATELLITE_TYPE,
                      region: {latitude: latitude, longitude: longitude, latitudeDelta:0.01, longitudeDelta:0.01},
                      animate:true,
                      regionFit:true,
                      userLocation:true
                  });
                  // mapview = Ti.UI.createView();
                  //mapview.setBackgroundImage("/images/bg.png");
                  MapsLoaded = true;
                   ContainerView.add(mapview);
                  CreateGrid();
              });
          }
      

      =========================

      Below code is use to take the screenshot / capture the map as image and saved. Image is in the proper
      place but in android it save as a black image.

      this.SaveImage = function(){
        var _storage = Ti.Filesystem.getFile(Ti.Filesystem.getExternalStorageDirectory()).getParent().nativePath;
        var file = Titanium.Filesystem.getFile(_storage , 'Downloads', 'mapview.png');
        file.write(mapview.toImage().media);
      }
      

      I have also used the below code but the result is same in android.

      
      Ti.Media.takeScreenshot(function(event){
      
         Ti.Media.saveToPhotoGallery(mapview.toImage().media);
      });
      

      How can I get this to work?

      — commented May 14th 2015 by ishit vohra
  • Anyone? :-/

    — answered June 29th 2010 by Dominik Hahn
    permalink
    0 Comments
  • Have you tried to change the name from 'backgroundImage'? Maybe it is getting confused because you would be setting it back to its own property?

    I didn't test it.. Just throwing an idea out! =)

    — answered June 30th 2010 by James Armstead
    permalink
    0 Comments
  • Thanks for your suggestion. :-)

    I tried it but sadly it doesn't work.

    — answered June 30th 2010 by Dominik Hahn
    permalink
    0 Comments
  • I dont know if you just missed it or not but the mapview.toImage is a function not a variable so you need to change it into mapview.toImage(); with the parenthases. Hope that helps.

    — answered June 30th 2010 by Kevin Smithson
    permalink
    1 Comment
    • Oh well, I tested several version. It looks like this now:

        var theMap = mapview.toImage();
        Titanium.API.info(theMap);
        var w = Ti.UI.createWindow({
          backgroundColor:'#FAFAFA',
          backgroundImage:theMap
        });
        win1.add(w);
      

      When I click the button that opens the window I get either the error from above or the simulator exists without an error message.

      Without the backgroundImage:theMap the console prints out:

      [INFO] [object TiBlob]
      

      — commented June 30th 2010 by Dominik Hahn
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.