2016-07-04 9 views
12

में बिटमैप छवि से थोड़ा मैट्रिक्स कॉपी करें मैं एक एंड्रॉइड ऐप विकसित कर रहा हूं जो उपयोगकर्ता को स्केचिंग या ड्राइंग द्वारा बिटमैप के हिस्से की प्रतिलिपि बनाने में मदद करता है। मेरा मतलब है कि उपयोगकर्ता कैनवास पर कुछ आकार खींचेंगे जिसमें बिटमैप पृष्ठभूमि के रूप में होगा और फिर मेरे पास पॉइंट्स हैं जो बिटमैप (बिट मैट्रिक्स/2 डी बिट सरणी) के रूप में रंगीन हैं। यहां तक ​​कि हर हिटंग अच्छा लगता है।एंड्रॉइड प्रोग्रामिंग

अब समस्या यह है कि मैं छवि के उस हिस्से की प्रतिलिपि कैसे बना सकता हूं जिसमें मैट्रिक्स में एक वास्तविक सत्य है? यदि आवश्यक हो तो अतिरिक्त जानकारी के लिए पूछें।

जोड़ना व्याख्या:

1) मुख्य छवि:

Image be fore any process

2) कैनवास पृष्ठभूमि के रूप में छवि:

Image as canvas background

3) कैनवास पर कुछ पेंटिंग:

User paints on canvas

4) बिट मैट्रिक्स चित्रित क्षेत्र के प्रतिनिधित्व:

Bit matrix

5) अपेक्षित आउटपुट:

Where is painted is outputted

अग्रिम धन्यवाद।

+0

बिट्स अनसेट कहां मौजूद होनी चाहिए? मेरा डिफ़ॉल्ट मूल्य क्या है। –

+0

@ पॉलस्टेलियन, वे पारदर्शी होंगे। मान लें कि छवि से सच्चे बिट्स काट दिया जाएगा! – ConductedClever

+0

फिर आप उस पारदर्शिता का प्रतिनिधित्व कैसे करेंगे? आपके पास किस प्रकार का आउटपुट है? पीएनजी? –

उत्तर

3

आप इसे ऐसा कर सकते हैं। उदाहरण स्रोत के रूप में Bitmap और फ़िल्टर मैट्रिक्स के रूप में Bitmap का उपयोग करता है।फिल्टर बिटमैप एक पारदर्शी पृष्ठभूमि है और इसलिए फ़िल्टर्ड बिटमैप है:

public Bitmap doFilter(Bitmap source, Bitmap filter) { 
    Bitmap filtered = Bitmap.createBitmap(source.getWidth(), source.getHeight(), source.getConfig()); 

    Paint paint = new Paint(); 
    Canvas canvas = new Canvas(filtered); 

    canvas.drawBitmap(source, 0, 0, paint); 
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); 
    canvas.drawBitmap(filter, 0, 0, paint); 

    return filtered; 
} 

उदाहरण के लिए, इस स्रोत के साथ:

enter image description here

और यह फिल्टर:

enter image description here

आपको यह फ़िल्टर की गई छवि मिलती है:

enter image description here

+0

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

+0

मैंने आपको कोड का परीक्षण किया है और यह अभी तक सबसे अच्छा काम किया गया था। धन्यवाद। TG। – ConductedClever

0

मेरे पास तीन बिटमैप्स होंगे। सबसे पहले आप पृष्ठभूमि के रूप में दिखाते हैं। दूसरा वह स्थान होगा जहां उपयोगकर्ता मुखौटा खींचता है और तीसरा परिणाम होगा।

पृष्ठभूमि छवि दिखाएं और उस के शीर्ष पर मास्क बिटमैप बनाएं। उपयोगकर्ता को मास्क पर आकर्षित करने दें। एक बार जब वे मुखौटा से खुश होते हैं तो बस पिक्सल पर फिर से चालू हो जाते हैं और जब आपको वह खाली लगता है जो खाली नहीं है तो आप जानते हैं कि यह एक पिक्सेल है जिसकी प्रतिलिपि बनाई जानी चाहिए। आपके पास अपने पुनरावृत्ति से पिक्सेल स्थिति होगी ताकि आप पृष्ठभूमि बिटमैप से उस स्थान पर पढ़ सकें और उस मान को बिटमैप के परिणाम में लिख सकें।

+0

आप मेरी व्याख्याओं को वापस अपने आप वापस कर रहे हैं। मुझे कुछ कामकाजी कोड चाहिए जो नॉन स्क्वायर पिक्चर आउट हो। – ConductedClever

2

अपने दिए गए स्पष्टीकरण के आधार पर मैं एक नमूना परियोजना निम्नलिखित बनाया और कोड नीचे दिया गया है -

public class ActivityImage extends AppCompatActivity{ 
Button grab; 
CustomImageView iv_custom; 
ImageView iv_later; 
Bitmap bitmapBG,bitmapOrg; 
int iMin,jMin,iMax,jMax; 
@Override 
protected void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.so_particular_img_section); 
    iv_custom = (CustomImageView)findViewById(R.id.iv_custom); 
    iv_custom.setDrawingCacheEnabled(true); 
    iv_later = (ImageView)findViewById(R.id.iv_later); 
    grab = (Button)findViewById(R.id.btn_grab); 
    grab.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      iv_custom.buildDrawingCache(); 
      bitmapBG = iv_custom.getDrawingCache(); 
      getSelectedRegionOnly(); 
     } 
    }); 
} 

/** 
* this method will return the whole image But only the selected region is highlighted and the rest section is simply white 
*/ 
private void getSelectedRegionWithBG(){ 
    int[] mainImageArray = iv_custom.getImagePixels(); 
    int[] bgImageArray = new int[bitmapBG.getWidth() * bitmapBG.getHeight()]; 
    int[] finalImageArray = new int[bitmapBG.getWidth() * bitmapBG.getHeight()]; 
    bitmapBG.getPixels(bgImageArray,0,bitmapBG.getWidth(), 0, 0, bitmapBG.getWidth(), bitmapBG.getHeight()); 

    if(mainImageArray.length == bgImageArray.length){ 
     for(int i = 0; i < (bitmapBG.getWidth() * bitmapBG.getHeight());i++){ 
      if(mainImageArray[i] == bgImageArray[i]){ 
       finalImageArray[i] = Color.WHITE; 
      }else{ 
       finalImageArray[i] = mainImageArray[i]; 
      } 
     } 

     Bitmap finalBitmap = Bitmap.createBitmap(bitmapBG.getWidth(), bitmapBG.getHeight(), Bitmap.Config.ARGB_8888); 
     // Set the pixels 
     finalBitmap.setPixels(finalImageArray, 0, finalBitmap.getWidth(), 0, 0, finalBitmap.getWidth(), finalBitmap.getHeight()); 
     iv_later.setImageBitmap(finalBitmap); 
    }else{ 
     Toast.makeText(ActivityImage.this,"Array length are not same",Toast.LENGTH_SHORT).show(); 
    } 

} 

/** 
* This method will select only the selected region from the main image and create the bitmap 
*/ 
private void getSelectedRegionOnly(){ 
    generateBounds(); 
    int count = 0; 
    int[] finalImageArray = new int[(1+iMax - iMin) * (1+jMax - jMin)]; 
    Bitmap finalBitmap = Bitmap.createBitmap((1+jMax - jMin), (1+iMax - iMin), Bitmap.Config.ARGB_8888); 
     for(int i = iMin; i <= iMax; i++){ 
      for(int j = jMin; j <= jMax; j++){ 
       if(bitmapBG.getPixel(j,i) != bitmapOrg.getPixel(j,i)) { 
        finalImageArray[count] = bitmapOrg.getPixel(j, i); 
       }else { 
        finalImageArray[count] = Color.WHITE; 
       } 
       count++; 
      } 
     } 
     // Set the pixels 
     finalBitmap.setPixels(finalImageArray, 0, finalBitmap.getWidth(), 0, 0, finalBitmap.getWidth(), finalBitmap.getHeight()); 
     iv_later.setImageBitmap(finalBitmap); 

} 

/** 
* generates the bound of the coloured region 
*/ 
private void generateBounds(){ 
    bitmapOrg = iv_custom.getMainBitmap(); 
    iMax = jMax = 0; 
    iMin = jMin = bitmapBG.getWidth() * bitmapBG.getHeight(); 
    for(int i = 0; i < bitmapBG.getHeight(); i++){ 
     for(int j = 0; j < bitmapBG.getWidth(); j++){ 
      if(bitmapBG.getPixel(j,i) != bitmapOrg.getPixel(j,i)){ 
       if(iMin > i){ 
        iMin = i; 
       } 
       if(jMin > j){ 
        jMin = j; 
       } 
       if(iMax < i){ 
        iMax = i; 
       } 
       if(jMax < j){ 
        jMax = j; 
       } 
      } 
     } 
    } 
} 


} 

लेआउट फ़ाइल -

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 
<Button 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:text="GRAB IMAGE" 
    android:id="@+id/btn_grab" 
    android:layout_alignParentBottom="true"/> 
    <LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#ffffff" 
    android:id="@+id/demo" 
    android:orientation="vertical" 
    android:layout_above="@id/btn_grab" 
    > 
    <com.wandertails.stackovrflw.CustomImageView 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:id="@+id/iv_custom" 
     android:layout_weight="1" /> 

    <ImageView 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:id="@+id/iv_later" 
     android:layout_weight="1"/> 
</LinearLayout> 
</RelativeLayout> 

अंत में कस्टम छवि देखें -

public class CustomImageView extends ImageView { 
int width,height; 
Bitmap sample; 

Context con; 
Paint paint=new Paint(); 
public CustomImageView(Context context) { 
    super(context); 
    con = context; 
} 

public CustomImageView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    con = context; 
} 

public CustomImageView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    con = context; 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    sample = createBackground(width,height,con); 
    canvas.drawBitmap(sample,0,0,paint); 
    canvas.drawBitmap(createForeground(width,height,con),0,0,paint); 
    paint.setColor(Color.RED); 
    //canvas.drawRect(400,400,600,600,paint); 
    //canvas.drawCircle(400,400,200,paint); 
} 

public int[] getImagePixels(){ 
    int[] pixels = new int[sample.getWidth() * sample.getHeight()]; 
    sample.getPixels(pixels, 0, sample.getWidth(), 0, 0, sample.getWidth(), sample.getHeight()); 
    return pixels; 
} 

public Bitmap getMainBitmap(){ 
    return sample; 
} 

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    super.onSizeChanged(w, h, oldw, oldh); 
    width = w; 
    height = h; 
} 

private Bitmap createBackground(int width, int height, Context con) { 
    Bitmap logo = null; 
    logo = BitmapFactory.decodeResource(con.getResources(), R.drawable.sample); 
    return Bitmap.createScaledBitmap(logo,width,height,true).copy(Bitmap.Config.ARGB_8888,true); 
} 

private Bitmap createForeground(int width, int height, Context con) { 
    Bitmap logo = null; 
    logo = BitmapFactory.decodeResource(con.getResources(), R.drawable.sample1); 
    return Bitmap.createScaledBitmap(logo,width,height,true).copy(Bitmap.Config.ARGB_8888,true); 
} 

} 

यहां कुछ हैं Here the green image is the pattern(like the yellow region of image 3 of yours) and the Horse image is the actual main image

Here the red colored shapes are patterns

कोड है कि नहीं अनुकूलित किया जा सकता है, लेकिन मुझे लगता है कि यह अपने उद्देश्य को पूरा करेगा - स्क्रीन शॉट्स कि मैं प्राप्त की। इसके अलावा, आप मास्क के रूप में किसी भी आकार या डिज़ाइन का उपयोग कर सकते हैं (वह क्षेत्र जिसे चुनने की आवश्यकता है), मुझसे पूछें कि आपको किसी स्पष्टीकरण की आवश्यकता है ..

+0

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

+0

एंटोनियो का जवाब स्पष्ट रूप से सही है यदि आपको केवल मास्किंग की आवश्यकता है, लेकिन मैंने यह उदाहरण बनाया है ताकि आपके पास निम्नलिखित लाभ हो - 1. आपको किसी भी फ़िल्टर बिटमैप की आवश्यकता नहीं है 2. कस्टम परिदृश्य में उपयोगकर्ता चुन सकते हैं (उदा। कहें कि उपयोगकर्ता चुनने के लिए उंगली को स्पर्श और खींच सकता है) छवि का कोई भी अनुभाग, यह कोड – Debu

+0

3 काम करेगा।अंत में कहें कि 200 x 200 छवि है और उपयोगकर्ता ने 40 x 40 का चयन किया है, दाएं-शीर्ष अनुभाग, फिर getSelectedRegionOnly() का उपयोग करके आप केवल चयनित अनुभाग का 40 x 40 बिटमैप प्राप्त कर सकते हैं। मुझे बाउंटी की आवश्यकता नहीं है, अगर मेरा कोड आपकी समस्या हल करता है, तो मेरा सबसे बड़ा इनाम – Debu

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