2012-03-08 14 views
6

मेरे ऐप में गंभीर मेमोरी समस्याओं को ट्रैक करने की प्रक्रिया में, मैंने अपने ऐप से कई ढेर डंप देखा, और अधिकांश समय मेरे पास एक बड़ा बिटमैप है जो मैं नहीं करता के बारे में पता नहीं हैवास्तव में एक एंड्रॉइड हीप डंप से लिया गया बिटमैप कैसे देखें

इसमें 9.4 एमबी, या 9,830,400 बाइट्स, या वास्तव में 1280x1920 छवि 4 बाइट प्रति पिक्सेल पर लेती है।

मैंने एक्लिप्स मैट में चेक किया है, यह वास्तव में एक बाइट [9830400] है, जिसमें एक आने वाला संदर्भ है जो android.graphics.Bitmap है।

मैं इसे एक फ़ाइल में डंप करना चाहता हूं और इसे देखने का प्रयास करना चाहता हूं। मैं समझ नहीं पा रहा हूं कि यह कहां से आ रहा है। मेरे सभी drawables में मेरी सबसे बड़ी छवि 640x960 पीएनजी है, जो 3 एमबी से कम लेता है।

मैंने ग्रहण को "फ़ाइल में प्रतिलिपि बनाने" के लिए उपयोग करने का प्रयास किया, लेकिन मुझे लगता है कि यह बस फ़ाइल में बफर प्रिंट करता है, और मुझे कोई छवि सॉफ़्टवेयर नहीं पता है जो बाइट्स की धारा पढ़ सकता है और इसे एक के रूप में प्रदर्शित कर सकता है 4 बाइट प्रति पिक्सेल छवि।

कोई विचार? किसी फ़ाइल के लिए बाइट सरणी डंप,/sdcard/img को धक्का, और इस तरह एक गतिविधि लोड:

@Override 
public void onCreate(final Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    try { 
     final File inputFile = new File("/sdcard/img"); 
     final FileInputStream isr = new FileInputStream(inputFile); 
     final Bitmap bmp = BitmapFactory.decodeStream(isr); 
     ImageView iv = new ImageView(this); 
     iv.setImageBitmap(bmp); 
     setContentView(iv); 
     Log.d("ImageTest", "Image was inflated"); 
    } catch (final FileNotFoundException e) { 
     Log.d("ImageTest", "Image was not inflated"); 
    } 
} 

मैं कुछ भी नहीं देखा था

यहाँ मैं क्या करने की कोशिश की है।

क्या आप जानते हैं कि छवि को एन्कोड किया गया है? मान लें कि इसे byte[] buffer में संग्रहीत किया गया है। buffer[0] लाल है, buffer[1] हरा, आदि है?

+0

कि सिर्फ देशी प्रतिपादन कैश नहीं है? क्या आप हार्डवेयर त्वरण सक्षम के साथ चलाते हैं? – Peterdk

+0

हाँ मेरे पास एचडब्ल्यू त्वरण है। लेकिन यह स्पष्ट नहीं करता है कि मेरा बिटमैप 200% क्यों बढ़ाया गया था और यह विशाल बिटमैप ढेर में क्यों आवंटित किया गया है, आईएमएचओ। –

+0

क्या आपके पास कोई भाग्य है कि यह पता लगाने के लिए कि यह छवि क्या थी? मेरे पास भी ऐसी नकली छवि है जो 1.1 एमबी लेती है और एंड्रॉइड प्रीलोडेड संसाधनों से आ रही है। जब मैं जीआईएमपी का उपयोग करके बाइट बफर के पूर्वावलोकन को देखता हूं, तो मुझे आकार 1044x270 की नीली रेडियल ढाल छवि दिखाई देती है। – c05mic

उत्तर

2

ठीक है - कुछ असफल प्रयासों के बाद, मुझे अंत में इस बाइट सरणी से कुछ मिला। मैंने बाइट सरणी को विंडोज बिटमैप फ़ाइल में कनवर्ट करने के लिए यह सरल सी प्रोग्राम लिखा था। अगर कोई दिलचस्पी लेता है तो मैं कोड छोड़ रहा हूं।
मैंने इसे VisualC 6.0 और gcc 3.4.4 के विरुद्ध संकलित किया है, इसे किसी भी ओएस (विंडोज, लिनक्स और मैकोज़ एक्स पर परीक्षण) पर काम करना चाहिए।

#include <stdio.h> 
#include <math.h> 
#include <string.h> 
#include <stdlib.h> 

/* Types */ 
typedef unsigned char byte; 
typedef unsigned short uint16_t; 
typedef unsigned int uint32_t; 
typedef int int32_t; 

/* Constants */ 
#define RMASK 0x00ff0000 
#define GMASK 0x0000ff00 
#define BMASK 0x000000ff 
#define AMASK 0xff000000 

/* Structures */ 
struct bmpfile_magic { 
    unsigned char magic[2]; 
}; 

struct bmpfile_header { 
    uint32_t filesz; 
    uint16_t creator1; 
    uint16_t creator2; 
    uint32_t bmp_offset; 
}; 

struct bmpfile_dibheader { 
    uint32_t header_sz; 
    uint32_t width; 
    uint32_t height; 
    uint16_t nplanes; 
    uint16_t bitspp; 
    uint32_t compress_type; 
    uint32_t bmp_bytesz; 
    int32_t hres; 
    int32_t vres; 
    uint32_t ncolors; 
    uint32_t nimpcolors; 

    uint32_t rmask, gmask, bmask, amask; 
    uint32_t colorspace_type; 
    byte colorspace[0x24]; 
    uint32_t rgamma, ggamma, bgamma; 
}; 

/* Displays usage info and exits */ 
void usage(char *cmd) { 
    printf("Usage:\t%s <img_src> <img_dest.bmp> <width> <height>\n" 
     "\timg_src:\timage byte buffer obtained from Eclipse MAT, using 'copy > save value to file' while selecting the byte[] buffer corresponding to an android.graphics.Bitmap\n" 
     "\timg_dest:\tpath to target *.bmp file\n" 
     "\twidth:\t\tpicture width, obtained in Eclipse MAT, selecting the android.graphics.Bitmap object and seeing the object member values\n" 
     "\theight:\t\tpicture height\n\n", cmd); 
    exit(1); 
} 

/* C entry point */ 
int main(int argc, char **argv) { 
    FILE *in, *out; 
    char *file_in, *file_out; 
    int w, h, W, H; 
    byte r, g, b, a, *image; 
    struct bmpfile_magic magic; 
    struct bmpfile_header header; 
    struct bmpfile_dibheader dibheader; 

    /* Parse command line */ 
    if (argc < 5) { 
     usage(argv[0]); 
    } 
    file_in = argv[1]; 
    file_out = argv[2]; 
    W = atoi(argv[3]); 
    H = atoi(argv[4]); 
    in = fopen(file_in, "rb"); 
    out = fopen(file_out, "wb"); 

    /* Check parameters */ 
    if (in == NULL || out == NULL || W == 0 || H == 0) { 
     usage(argv[0]); 
    } 

    /* Init BMP headers */ 
    magic.magic[0] = 'B'; 
    magic.magic[1] = 'M'; 

    header.filesz = W * H * 4 + sizeof(magic) + sizeof(header) + sizeof(dibheader); 
    header.creator1 = 0; 
    header.creator2 = 0; 
    header.bmp_offset = sizeof(magic) + sizeof(header) + sizeof(dibheader); 

    dibheader.header_sz = sizeof(dibheader); 
    dibheader.width = W; 
    dibheader.height = H; 
    dibheader.nplanes = 1; 
    dibheader.bitspp = 32; 
    dibheader.compress_type = 3; 
    dibheader.bmp_bytesz = W * H * 4; 
    dibheader.hres = 2835; 
    dibheader.vres = 2835; 
    dibheader.ncolors = 0; 
    dibheader.nimpcolors = 0; 
    dibheader.rmask = RMASK; 
    dibheader.gmask = BMASK; 
    dibheader.bmask = GMASK; 
    dibheader.amask = AMASK; 
    dibheader.colorspace_type = 0x57696e20; 
    memset(&dibheader.colorspace, 0, sizeof(dibheader.colorspace)); 
    dibheader.rgamma = dibheader.bgamma = dibheader.ggamma = 0; 

    /* Read picture data */ 
    image = (byte*) malloc(4*W*H); 
    if (image == NULL) { 
     printf("Could not allocate a %d-byte buffer.\n", 4*W*H); 
     exit(1); 
    } 
    fread(image, 4*W*H, sizeof(byte), in); 
    fclose(in); 

    /* Write header */ 
    fwrite(&magic, sizeof(magic), 1, out); 
    fwrite(&header, sizeof(header), 1, out); 
    fwrite(&dibheader, sizeof(dibheader), 1, out); 

    /* Convert the byte array to BMP format */ 
    for (h = H-1; h >= 0; h--) { 
     for (w = 0; w < W; w++) { 
      r = *(image + w*4 + 4 * W * h); 
      b = *(image + w*4 + 4 * W * h + 1); 
      g = *(image + w*4 + 4 * W * h + 2); 
      a = *(image + w*4 + 4 * W * h + 3); 

      fwrite(&b, 1, 1, out); 
      fwrite(&g, 1, 1, out); 
      fwrite(&r, 1, 1, out); 
      fwrite(&a, 1, 1, out); 
     } 
    } 

    free(image); 
    fclose(out); 
} 

तो इस उपकरण मैं इस 1280x1920 बिटमैप उत्पन्न करने के लिए इस्तेमाल किया चित्र पहचान करने में सक्षम था का उपयोग कर।

+0

मैं सोच रहा था कि क्या आपने मैक ओएसएक्स पर किसी भी विशेष तरीके से बाइट सरणी की सामग्री को सहेजा है? मैं आपके कोड को संकलित करने और इसे मैट से सहेजी गई फ़ाइल की सामग्री के विरुद्ध चलाने में सक्षम था लेकिन परिणामस्वरूप बीएमपी को मैक के पूर्वावलोकन छवि दर्शक द्वारा पढ़ा नहीं जा सकता है (मूल फ़ाइल के साथ कुछ गड़बड़ कर रहा है क्योंकि कोड त्रुटि नहीं करता है) –

+0

मुझे बिल्कुल याद नहीं है, मैंने अभी मैट से एक्लिप्स की "प्रतिलिपि मूल्य फ़ाइल" का उपयोग किया है, और इस फ़ाइल के खिलाफ मेरा सी प्रोग्राम चलाया है। –

0

बस फ़ाइल में इनपुट लें और फ़ाइलइनपुट स्ट्रीम/डेटास्ट्रीम का उपयोग कर इसे बिटमैप ऑब्जेक्ट में परिवर्तित करें। उपयोग की जाने वाली प्रत्येक छवि के लिए डेटा देखने के लिए लॉग भी जोड़ें।

+0

मैंने कोशिश की लेकिन यह कुछ भी प्रदर्शित नहीं कर रहा है ... मेरा संपादन देखें। –

0

आप एक यूएसबी कनेक्शन सक्षम कर सकते हैं और फाइल को अन्य कंप्यूटरों में कॉपी करने के लिए अधिक टूल्स के साथ प्रतिलिपि बना सकते हैं।

स्टार्ट बटन दबाए जाने पर वर्तमान डिवाइस को सिस्टम सिस्टम में डंप करने के लिए कुछ डिवाइस कॉन्फ़िगर किए जा सकते हैं। शायद यह आपके साथ होता है।

+0

आपको बहुत धन्यवाद, लेकिन मुझे नहीं लगता कि यह मेरे मुद्दे के लिए कैसे प्रासंगिक है, और यह कैसे एक हेप डंप से लिया गया बाइट सरणी को देखने योग्य छवि प्रारूप में परिवर्तित करने में मेरी मदद कर सकता है। –

0

के रूप में छवि को लोड मैंने पाया कि के रूप में एंड्रॉयड स्टूडियो का नवीनतम संस्करण (2.2.2 से शुरू लेखन), आप सीधे बिटमैप फ़ाइल देख सकते हैं:

  1. 'एंड्रॉइड मॉनीटर' टैब (नीचे बाईं ओर) और फिर मेमोरी टैब खोलें।
  2. प्रेस 'डंप जावा ढेर' बटन

  3. चुनें 'बिटमैप' वर्ग नाम वर्तमान स्नैपशॉट के लिए, बिटमैप के प्रत्येक उदाहरण का चयन करें और देखने के लिए क्या छवि वास्तव में अधिक स्मृति की खपत उम्मीद से। (स्क्रीन 4 और 5)

  4. Bitmap वर्ग के नाम चुनें ...

enter image description here

  1. बिटमैप

enter image description here के प्रत्येक उदाहरण का चयन करें

और उस पर राइट क्लिक करें , चयन View Bitmap

enter image description here

संबंधित मुद्दे