2016-06-29 19 views
8

में छवि पिक्सेल डेटा तक कैसे पहुंचे मेरे पास एक छवि है जो कैमरा रोल या किसी अन्य स्रोत से लोड की गई थी, आमतौर पर स्थानीय एक।प्रतिक्रिया-मूल

कुछ गणना या माप करने के लिए मैं अपने पिक्सेल डेटा मानचित्र को कैसे एक्सेस कर सकता हूं?

+1

क्या आपको कभी इसका समाधान मिला? – James

+1

मुझे लगता है कि आप छवि को कैनवास में खींच सकते हैं, फिर डेटा मैप प्राप्त करने के लिए 'getImageData() 'का उपयोग करें: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData। हालांकि, यह एक प्रतिक्रिया आधारित समाधान नहीं है। –

उत्तर

9

देशी मॉड्यूल का उपयोग करके यह जानकारी प्राप्त करने का एक तरीका है, लेकिन इस समय मेरे पास केवल एंड्रॉइड कार्यान्वयन है। आरएन 0.42.3 पर परीक्षण किया। सबसे पहले, आपको अपने ऐप में देशी मॉड्यूल बनाना होगा। यह मानते हुए कि आवेदन नाम SampleApp साथ आरंभ नहीं हो जाता है, अपने उस में दो फाइलों के साथ प्रतिक्रिया मूल निवासी परियोजना android/app/src/main/java/com/sampleapp/bitmap में नई निर्देशिका बनाने के लिए:

एंड्रॉयड/ऐप्स/src/मुख्य/जावा/com/SampleApp/बिटमैप/BitmapReactPackage.java

package com.sampleapp; 

import com.facebook.react.ReactPackage; 
import com.facebook.react.bridge.JavaScriptModule; 
import com.facebook.react.bridge.NativeModule; 
import com.facebook.react.bridge.ReactApplicationContext; 
import com.facebook.react.uimanager.ViewManager; 

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

public class BitmapReactPackage implements ReactPackage { 

    @Override 
    public List<Class<? extends JavaScriptModule>> createJSModules() { 
    return Collections.emptyList(); 
    } 

    @Override 
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { 
    return Collections.emptyList(); 
    } 

    @Override 
    public List<NativeModule> createNativeModules(
           ReactApplicationContext reactContext) { 
    List<NativeModule> modules = new ArrayList<>(); 

    modules.add(new BitmapModule(reactContext)); 

    return modules; 
    } 

} 

एंड्रॉयड/ऐप्स/src/मुख्य/जावा/com/SampleApp/बिटमैप/BitmapModule.java

package com.sampleapp; 

import com.facebook.react.bridge.NativeModule; 
import com.facebook.react.bridge.ReactApplicationContext; 
import com.facebook.react.bridge.ReactContext; 
import com.facebook.react.bridge.ReactContextBaseJavaModule; 
import com.facebook.react.bridge.ReactMethod; 
import com.facebook.react.bridge.Promise; 
import com.facebook.react.bridge.WritableNativeArray; 
import com.facebook.react.bridge.WritableNativeMap; 

import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 

import java.io.IOException; 

public class BitmapModule extends ReactContextBaseJavaModule { 

    public BitmapModule(ReactApplicationContext reactContext) { 
    super(reactContext); 
    } 

    @Override 
    public String getName() { 
    return "Bitmap"; 
    } 

    @ReactMethod 
    public void getPixels(String filePath, final Promise promise) { 
    try { 
     WritableNativeMap result = new WritableNativeMap(); 
     WritableNativeArray pixels = new WritableNativeArray(); 

     Bitmap bitmap = BitmapFactory.decodeFile(filePath); 
     if (bitmap == null) { 
     promise.reject("Failed to decode. Path is incorrect or image is corrupted"); 
     return; 
     } 

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

     boolean hasAlpha = bitmap.hasAlpha(); 

     for (int x = 0; x < width; x++) { 
     for (int y = 0; y < height; y++) { 
      int color = bitmap.getPixel(x, y); 
      String hex = Integer.toHexString(color); 
      pixels.pushString(hex); 
     } 
     } 

     result.putInt("width", width); 
     result.putInt("height", height); 
     result.putBoolean("hasAlpha", hasAlpha); 
     result.putArray("pixels", pixels); 

     promise.resolve(result); 

    } catch (Exception e) { 
     promise.reject(e); 
    } 

    } 

} 

आप दूसरी फ़ाइल में देख सकते हैं कि वहाँ एक विधि getPixels, जिसमें से उपलब्ध हो जाएगा है एक के रूप में जेएस Bitmap मूल मॉड्यूल का हिस्सा। यह एक छवि फ़ाइल के लिए पथ स्वीकार करता है, छवि को एक आंतरिक बिटमैप प्रकार में परिवर्तित करता है, जो छवि पिक्सल को पढ़ने की अनुमति देता है। सभी छवि पिक्सल एक-एक करके पढ़े जाते हैं और हेक्स स्ट्रिंग्स के रूप में पिक्सेल की सरणी में सहेजे जाते हैं (क्योंकि प्रतिक्रिया मूल पुल के माध्यम से हेक्स मानों को पार करने की अनुमति नहीं देता है)। इन हेक्स स्ट्रिंग्स में 8 वर्ण हैं, प्रति ARGB चैनल के 2 वर्ण हैं: पहले दो अक्षर अल्फा चैनल के लिए हेक्स मान है, दूसरा दो - लाल, तीसरे दो - हरे रंग के लिए और अंतिम दो - नीले चैनल के लिए। उदाहरण के लिए, मान ffffffff - एक सफेद रंग और ff0000ff है - एक नीला रंग है। सुविधा के लिए, छवि चौड़ाई, ऊंचाई और अल्फा चैनल की उपस्थिति पिक्सेल की सरणी के साथ वापस कर दी जाती है। विधि एक वस्तु के साथ एक वादा रिटर्न:

{ 
    width: 1200, 
    height: 800, 
    hasAlpha: false, 
    pixels: ['ffffffff', 'ff00ffff', 'ffff00ff', ...] 
} 

मूल निवासी मॉड्यूल भी अनुप्रयोग में पंजीकृत किया जाना है, android/app/src/main/java/com/sampleapp/MainApplication.java को संशोधित करने और वहाँ में नए मॉड्यूल जोड़ें:

@Override 
protected List<ReactPackage> getPackages() { 
    return Arrays.<ReactPackage>asList(
     new MainReactPackage(), 
     new BitmapReactPackage() // <--- 
); 
} 

कैसे जे एस से उपयोग करने के लिए:

import { NativeModules } from 'react-native'; 

const imagePath = '/storage/emulated/0/Pictures/blob.png'; 

NativeModules.Bitmap.getPixels(imagePath) 
    .then((image) => { 
    console.log(image.width); 
    console.log(image.height); 
    console.log(image.hasAlpha); 


    for (let x = 0; x < image.width; x++) { 
     for (let y = 0; y < image.height; y++) { 
     const offset = image.width * y + x; 
     const pixel = image.pixels[offset]; 
     } 
    } 
    }) 
    .catch((err) => { 
    console.error(err); 
    }); 

मुझे उल्लेख करने की ज़रूरत है कि यह पुल के माध्यम से एक विशाल सरणी को स्थानांतरित करने की वजह से बहुत धीमी गति से प्रदर्शन करता है।

+1

आपके उत्तर के लिए धन्यवाद! ऐसा लगता है कि देशी मॉड्यूल जाने का रास्ता है। वैसे, [एंड्रॉइड एपीआई] (https://developer.android.com/reference/android/graphics/Color.html) का उल्लेख है कि रंग एआरजीबी क्रम में एन्कोड किए गए हैं, आरजीबीए नहीं। आपने बताया है कि "हेक्स मान" समर्थित नहीं हैं। पूर्णांक सरणी * वास्तव में * समर्थित नहीं हैं? यह महत्वपूर्ण नहीं है कि किसी भी छवि प्रसंस्करण को मूल रूप से देशी पक्ष पर किया जाना चाहिए। – cubrr

+1

@ क्यूबर, आप सही हैं, मैंने इस पर पर्याप्त ध्यान नहीं दिया। रंग वास्तव में एआरजीबी हैं। हेक्स के बारे में: मैंने रंग मान को पारित करने का प्रयास किया जो सीधे पुल के माध्यम से 'bitmap.getPixel (x, y)' कॉल से वापस लौटाया गया है, लेकिन मुझे प्राप्त किए गए int मान मेरे लिए बहुत जानकारीपूर्ण नहीं थे, ये एक गुच्छा हैं नकारात्मक इंक जेएस में 'pixel.toString (16)' निष्पादित करने के बाद बेहतर हो गया। उदाहरण के लिए: '(-4153434) .toString (16) =" -3f605a "'। मुझे लगता है कि यह तय करने के लिए आप पर निर्भर है कि आप कौन सा प्रारूप पसंद करते हैं। –

+0

आह, दाएं, जावा में हस्ताक्षरित संख्याएं नहीं हैं इसलिए निश्चित रूप से वे नकारात्मक हो सकते हैं।काम क्या हो सकता है लंबे समय से गुजर रहा है: 'लंबा रंग = bitmap.getPixel (x, y) और 0xFFFFFFFFL' – cubrr