2012-02-21 18 views
16

मैं एक मोबाइल ब्लूटूथ प्रिंटर (बिक्सोलन एसपीपी-आर 200) में बिटमैप प्रिंट करना चाहता हूं - एसडीके एक मेमोरी प्रिंट करने के लिए सख्त तरीकों की पेशकश नहीं करता है छवि। एक मोनोक्रोम बिटमैप करने के लिएएंड्रॉइड: एक बिटमैप को एक मोनोक्रोम बिटमैप में परिवर्तित करना (1 बिट प्रति पिक्सेल)

Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 

: तो मैं इस तरह एक बिटमैप परिवर्तित करने के बारे में सोचा। मैं एक कैनवास का उपयोग कर उपरोक्त दिए गए बिटमैप पर काले पाठ खींच रहा हूं, जो अच्छी तरह से काम करता है। हालांकि, जब मैं उपरोक्त बिटमैप को बाइटएरे में परिवर्तित करता हूं, तो प्रिंटर उन बाइट्स को संभालने में असमर्थ लगता है। मुझे संदेह है कि मुझे एक बिट प्रति पिक्सेल के साथ एक ऐरे की आवश्यकता है (एक पिक्सेल या तो सफेद = 1 या काला = 0 होगा)।

bitmap.getPixels(pixels, offset, stride, x, y, width, height) 

पिक्सल प्राप्त करने के लिए:

वहाँ बॉक्स तरीका है कि ऐसा करने के लिए से बाहर, कोई सुविधाजनक हो रहा है के रूप में, एक विचार मैं था इस्तेमाल किया गया। मुझे लगता है मैं इसे उपयोग करने के लिए इस प्रकार होगा,:

int width = bitmap.getWidth(); 
int height = bitmap.getHeight(); 

int [] pixels = new int [width * height]; 
bitmap.getPixels(pixels, 0, width, 0, 0, width, height); 

हालांकि - मैं कुछ चीजों के बारे में सुनिश्चित नहीं हूं:

  • getPixels में - यह मतलब है बस के रूप में पारित करने के लिए चौड़ाई "स्ट्रइड" तर्क?
  • मुझे लगता है कि मुझे प्रत्येक पिक्सेल की रंगीन जानकारी का मूल्यांकन करना होगा और या तो इसे काला या सफेद पर स्विच करना होगा (और मैं इस मान को एक नए लक्ष्य बाइट सरणी में लिखूंगा जिसे मैं आखिरकार प्रिंटर पर भेजूंगा)?
  • यह तय करने के लिए कि यह काला या सफेद होना चाहिए, प्रत्येक पिक्सेल रंग की जानकारी का सर्वोत्तम मूल्यांकन कैसे करें? (गाया बिटमैप एक सफेद पृष्ठभूमि पर काले दर्द है)

इस दृष्टिकोण बिल्कुल मतलब है? क्या कोई आसान तरीका है? बिटमैप ब्लैक & सफेद बनाने के लिए पर्याप्त नहीं है, मुख्य मुद्दा प्रत्येक पिक्सेल के लिए रंग जानकारी को एक बिट में कम करना है।

अद्यतन

के रूप में सुझाव दिया रूबेन द्वारा मैं पहली बार एक मोनोक्रोम बिटमैप करने के लिए बिटमैप बदल देंगे। और फिर मैं प्रत्येक पिक्सेल से अधिक पुनरावृति होगी:

int width = bitmap.getWidth(); 
    int height = bitmap.getHeight(); 

    int[] pixels = new int[width * height]; 
    bitmap.getPixels(pixels, 0, width, 0, 0, width, height); 

    // Iterate over height 
    for (int y = 0; y < height; y++) { 
     int offset = y * height; 
     // Iterate over width 
     for (int x = 0; x < width; x++) { 
      int pixel = bitmap.getPixel(x, y); 
     } 
    } 

अब रूबेन "प्रत्येक 32-बिट पिक्सेल का सबसे कम बाइट पढ़ें" करने का सुझाव दिया - कि कैसे पिक्सेल रंग का मूल्यांकन करने के बारे में मेरे सवाल से संबंधित होगा। इस संबंध में मेरी आखिरी सवाल: मैं बस ऐसा करने से सबसे कम बाइट मिलता है:

// Using the pixel from bitmap.getPixel(x,y) 
int lowestByte = pixel & 0xff; 
+0

मैं इस क्यूए अभिनय किया है क्योंकि मैं एक ऐसी ही अवधारणा पर काम कर रहा था मोनोक्रोम बिटमैप्स बनने के लिए प्रोग्रामेटिक रूप से एरेज़ में हेरफेर करने के संबंध में। मेरे पास एक प्रश्न है और इसका अंतिम उत्तर यहां दिया गया है: http://stackoverflow.com/questions/17918978/plot-an-array-into-bitmap-in-cc-for-thermal-printer अगर यह लोगों की सहायता करता है, तो कृपया मुझे ईमेल करें और मैं इस प्रश्न के उपयुक्त उत्तर के साथ आऊंगा। –

+0

क्यों आप एक ही सरणी में सभी पिक्सल लोड करने के लिए GetPixels उपयोग कर रहे हैं ... तो फिर बिटमैप के माध्यम से फिर से (कम से कम प्रभावी तरीके से) पाशन व्यक्ति GetPixel कॉल बुला नेस्ट? बस अपनी मूल सरणी के माध्यम से लूप करें, फिर संपूर्ण सरणी को वापस बिटमैप में धक्का देने के लिए SetPixels का उपयोग करें। –

+0

@ClintStLaurent अच्छा बिंदु - कोड वास्तव में पुराना एक्सडी है - मुझे यह भी नहीं लगता कि हम इसे इस रूप में उपयोग कर रहे हैं, लेकिन जैसा कि आपने सही तरीके से बताया है, यह बहुत ही अक्षम है जिस तरह से यह लिखा गया है। अपने सुझाव के अनुसार इसे संपादित करने के लिए स्वतंत्र महसूस करें। – AgentKnopf

उत्तर

18

आप एक COLORMATRIX का उपयोग कर 32bpp मोनोक्रोम छवि बदल सकते हैं।

Bitmap bmpMonochrome = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
Canvas canvas = new Canvas(bmpMonochrome); 
ColorMatrix ma = new ColorMatrix(); 
ma.setSaturation(0); 
Paint paint = new Paint(); 
paint.setColorFilter(new ColorMatrixColorFilter(ma)); 
canvas.drawBitmap(bmpSrc, 0, 0, paint); 

जो रंग-> मोनोक्रोम रूपांतरण को सरल बनाता है। अब आप केवल getPixels() कर सकते हैं और प्रत्येक 32-बिट पिक्सेल के निम्नतम बाइट को पढ़ सकते हैं। यदि यह < 128 है यह एक 0 है, अन्यथा यह एक 1.

+0

आपके उत्तर के लिए बहुत बहुत धन्यवाद! बस स्पष्ट करने के लिए पिक्सेल मूल्यांकन मैं मेरे सवाल का अद्यतन (अद्यतन नीचे) अनिवार्य रूप से: पूर्णांक lowestByte = पिक्सेल & 0xff;: मैं ऐसा करने से एक 32-बिट पूर्णांक के सबसे कम बाइट मिलता है? – AgentKnopf

+1

हां। असल में सबसे कम बाइट का बिट 7 बिल्कुल ठीक है जिसे आप अपने 1 बीपीपी पिक्सेल के लिए चाहते हैं। अभिव्यक्ति '(पिक्सेल और 0x80) >> 7' आपको इसके लिए '0' या '1' देगी। –

+0

वाह धन्यवाद :)! – AgentKnopf

10

खैर मुझे लगता है कि इसकी काफी देर से अब इस थ्रेड पर जवाब के लिए, लेकिन मैं भी इस सामान पर कभी कभी वापस काम कर रहा था और अपने खुद के पुस्तकालय है कि किसी भी परिवर्तित कर देंगे निर्माण करने का फैसला जेपीजी या पीएनजी छवि 1bpp .bmp करने के लिए। अधिकांश प्रिंटर जिन्हें 1 बीपीपी छवियों की आवश्यकता होती है, इस छवि का समर्थन करेंगे (उन में से एक पर परीक्षण :))। यहां आप लाइब्रेरी के साथ-साथ एक टेस्ट प्रोजेक्ट भी ढूंढ सकते हैं जो मोनोक्रोम एकल चैनल छवि बनाने के लिए इसका उपयोग करता है। इसे बदलने के लिए स्वतंत्र महसूस करें ..:)

https://github.com/acdevs/1bpp-monochrome-android

का आनंद लें .. !! :)

+0

प्रयास के लिए धन्यवाद! मुझे यकीन है कि यह दूसरों के लिए सहायक होगा और मैं आपके द्वारा पोस्ट की गई परियोजना पर एक नज़र डालेगा :)। – AgentKnopf

5

मूल बिटमैप के समान आकार के साथ मोनोक्रोम में कनवर्ट करना प्रिंट करने के लिए पर्याप्त नहीं है।

प्रिंटर केवल "पिक्सेल" (डॉट) को मोनोक्रोम के रूप में प्रिंट कर सकते हैं क्योंकि स्याही के प्रत्येक स्थान में केवल 1 रंग होता है, इसलिए उन्हें पर्याप्त से अधिक बिंदुओं का उपयोग करना चाहिए और उनके आकार, घनत्व को समायोजित करना होगा ... ग्रेस्केल- महसूस की तरह इस तकनीक को halftoning कहा जाता है। आप देख सकते हैं कि प्रिंटर अक्सर कम से कम 600 डीपीआई संकल्प करते हैं, आमतौर पर 1200-4800 डीपीआई, जबकि डिस्प्ले स्क्रीन अक्सर 200-300ppi पर सबसे ऊपर होती है।

Halftone

तो अपने मोनोक्रोम बिटमैप कम से कम 3 बार प्रत्येक पक्ष में मूल संकल्प होना चाहिए।

+0

क्या आप किसी भी मौके से डूबने का मतलब है? मैं पहले से ही मेरे कोड :) – AgentKnopf

+0

सं हिचकिचाहट एक comletely विभिन्न व्यावसायिक है में एकीकृत dithering था। 8 बिट या अधिक ग्रेस्केल बिटमैप में ग्रे का स्तर (आप कितने बिट का उपयोग पर निर्भर करता है या अधिक,) 255 है, तो मूल संकल्प ठीक है। लेकिन यदि आप मोनोक्रोम बिटमैप का उपयोग करते हैं तो लगभग सभी विवरण महत्वपूर्ण रूप से खो जाएंगे क्योंकि आप 16.7 मिलियन से अधिक रंगों से केवल 2 तक कम हो रहे हैं। हाफटनिंग संकल्प बढ़ाती है और इस सीमा को पार करने के तरीके के रूप में ग्रेस्केल के प्रभाव को देने के लिए अतिरिक्त पिक्सेल का उपयोग करती है। आप ऊपर दिए गए लिंक का संदर्भ दे सकते हैं। –

+0

आह, इसे साफ़ करने के लिए धन्यवाद :)! मेरे विशेष उपयोग-मामले में मैं पहले से ही काले और सफेद रंग में कैनवास पर आकर्षित करता हूं। लेकिन यह भी हो सकता है कि हम तस्वीरों प्रिंट, इसलिए इन मामलों के लिए हाफ़-टोनिंग वास्तव में उपयोगी हो सकता है - फिर से धन्यवाद :)! – AgentKnopf

1

आप एचएसवी अंतरिक्ष में प्रत्येक पिक्सेल बदलने और निर्धारित करने के लिए लक्ष्य छवि पर पिक्सेल काला या सफेद होना चाहिए मूल्य का उपयोग करना चाहिए:

Bitmap bwBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.RGB_565); 
    float[] hsv = new float[ 3 ]; 
    for(int col = 0; col < bitmap.getWidth(); col++) { 
    for(int row = 0; row < bitmap.getHeight(); row++) { 
     Color.colorToHSV(bitmap.getPixel(col, row), hsv); 
     if(hsv[ 2 ] > 0.5f) { 
     bwBitmap.setPixel(col, row, 0xffffffff); 
     } else { 
     bwBitmap.setPixel(col, row, 0xff000000); 
     } 
    } 
    } 
    return bwBitmap; 
संबंधित मुद्दे