2016-06-29 26 views
8

Fotoğraf makinenizden veya genellikle yerel olan başka herhangi bir kaynaktan yüklenen bir Resim var.Reaktif yerel görüntü piksel verilerine nasıl erişilir

Bazı hesaplamalar veya ölçümler yapmak için piksel veri haritasına nasıl erişebilirim?

+1

Buna bir çözüm buldunuz mu? – James

+1

Görüntüyü bir tuvale çizebileceğinizi düşünüyorum, daha sonra veri haritasını almak için 'getImageData()' yi kullanın: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData. Her ne kadar React tabanlı bir çözüm değildir. –

cevap

9

Bu bilgiyi yerel modülleri kullanarak almanın bir yolu var, ancak şu anda yalnızca Android uygulamasına sahibim. RN 0.42.3 üzerinde test edilmiştir. Her şeyden önce, uygulamanızda yerel bir modül oluşturmanız gerekir. bu uygulama adı SampleApp başlatılır varsayarsak, sizin içinde iki dosyalarla Yerli projeyi android/app/src/main/java/com/sampleapp/bitmap Tepki de yeni bir dizin oluşturun:

android/app/src/main/java/com/SampleApp/bitmap/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; 
    } 

} 

android/app/src/main/java/com/SampleApp/bitmap/BitmapModule.java ikinci dosyada görebileceğiniz gibi

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); 
    } 

    } 

} 

itibaren satışa sunulacak bir yöntem getPixels vardır JS olarak Bitmap yerel modülün parçası. Bir görüntü dosyasına giden yolu kabul eder, görüntüyü pikselleri okumasına izin veren dahili bir Bitmap türüne dönüştürür. Tüm görüntü pikselleri birer birer okunur ve bir piksel dizisi biçiminde piksel dizisine kaydedilir (çünkü React Native, köprüden altıgen değerlerini geçmesine izin vermez). Bu hex dizeleri 8 karakter, ARGB kanal başına 2 karakterden oluşur: ilk iki karakter alfa kanalı için bir hex değeri, ikinci ikisi - kırmızı, üçüncü ikisi için - yeşil için ve son ikisi - mavi kanal için. Örneğin, ffffffff - beyaz renktir ve ff0000ff - mavi renktir. Kolaylık sağlamak için, görüntü genişliği, yükseklik ve alfa kanalı varlığı piksel dizisiyle birlikte iade edilir. android/app/src/main/java/com/sampleapp/MainApplication.java değiştirmek ve orada yeni bir modül eklemek

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

Yerli modül ayrıca app kayıtlı olması gerekir:

@Override 
protected List<ReactPackage> getPackages() { 
    return Arrays.<ReactPackage>asList(
     new MainReactPackage(), 
     new BitmapReactPackage() // <--- 
); 
} 
JS dan nasıl kullanılır

: Yöntem bir nesne ile bir söz verir

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); 
    }); 

Köprüden devasa bir dizinin aktarılması nedeniyle oldukça yavaş çalıştığından bahsetmem gerek.

+1

Cevabınız için teşekkürler! Yerel modüller gitmenin yolu gibi görünüyor. Bu arada, [Android API] (https://developer.android.com/reference/android/graphics/Color.html), renklerin RGBA değil, ARGB düzeninde kodlandığından bahseder. "Onaltılık değerler" in desteklenmediğini belirttiniz. Tamsayı dizileri * gerçekten * desteklenmiyor mu? Önemli değil, herhangi bir görüntü işleme muhtemelen zaten yerli tarafında yapılmalıdır. – cubrr

+1

@cubrr, haklısınız, buna yeterince dikkat etmedim. Renkler gerçekten ARGB'dir. Onaltılı olarak: Köprüden doğrudan 'bitmap.getPixel (x, y)' çağrısından döndürülen renk değerini iletmeye çalıştım ancak aldığım int değerleri bana çok bilgilendirici değildi, bunlar bir grup negatif değerler. JS içinde 'pixel.toString (16)' yi çalıştırdıktan sonra daha iyi oldu. Örneğin: '(-4153434) .toString (16) =" -3f605a "'. Hangi formatı tercih edeceğinize karar vermek size kalmış. –

+0

Ah, sağda, Java imzasız numaralara sahip değil, dolayısıyla negatif olabilirler.Çalışmalar uzun yıllar geçebilir: 'long color = bitmap.getPixel (x, y) & 0xFFFFFFFFL' – cubrr

İlgili konular