2016-02-14 9 views
5

मैं JPEG फ़ाइल लोड और सब काले और सफेद पिक्सलनेट Bitmap.Load विधि विभिन्न कंप्यूटरों पर अलग अलग परिणाम उपज

सी # कोड छवि से हटाने का प्रयास: मैं खोजने की कोशिश उसके बाद

... 
    m_SrcImage = new Bitmap(imagePath); 

    Rectangle r = new Rectangle(0, 0, m_SrcImage.Width, m_SrcImage.Height); 
    BitmapData bd = m_SrcImage.LockBits(r, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); 

    //Load Colors 
    int[] colours = new int[m_SrcImage.Width * m_SrcImage.Height]; 
    Marshal.Copy(bd.Scan0, colours, 0, colours.Length); 
    m_SrcImage.UnlockBits(bd); 

    int len = colours.Length; 

    List<Color> result = new List<Color>(len); 

    for (int i = 0; i < len; ++i) 
    { 
     uint w = ((uint)colours[i]) & 0x00FFFFFF; //Delete alpha-channel 
     if (w != 0x00000000 && w != 0x00FFFFFF) //Check pixel is not black or white 
     { 
      w |= 0xFF000000;      //Return alpha channel 
      result.Add(Color.FromArgb((int)w)); 
     } 
    } 
    ... 

इस कोड द्वारा सूची में अद्वितीय रंग

result.Sort((a, b) => 
    { 
     return a.R != b.R ? a.R - b.R : 
       a.G != b.G ? a.G - b.G : 
       a.B != b.B ? a.B - b.B : 
       0; 
    }); 


    List<Color> uniqueColors = new List<Color>(result.Count); 

    Color rgbTemp = result[0]; 

    for (int i = 0; i < len; ++i) 
    { 
     if (rgbTemp == result[i]) 
     {  
       continue; 
     } 

     uniqueColors.Add(rgbTemp); 
     rgbTemp = result[i]; 
    } 
    uniqueColors.Add(rgbTemp); 

और यह कोड एक ही छवि पर विभिन्न मशीनों पर अलग-अलग परिणाम उत्पन्न करता है!

उदाहरण के लिए, this image पर यह निर्माण करता है:

  • 43198 अद्वितीय रंग XP SP3 पर नेट संस्करण के साथ नेट संस्करण के साथ Win7 अंतिम पर 4
  • 43,168 अद्वितीय रंग 4,5

न्यूनतम परीक्षण परियोजना आप download here कर सकते हैं। यह सिर्फ चयनित छवि खुलता है और अद्वितीय रंगों के साथ txt-file उत्पन्न करता है।

एक और तथ्य। कुछ पिक्सेल अलग-अलग मशीनों पर अलग-अलग पढ़े जाते हैं। मैं txt-files को नोटपैड ++ के साथ तुलना करता हूं और यह दिखाता है कि कुछ पिक्सेल में अलग-अलग आरजीबी घटक होते हैं। प्रत्येक घटक के लिए अंतर 1 है, उदा।

  • Win7 पिक्सेल: 255 200 100
  • WinXP पिक्सेल: 254 199 99

मैं इस पोस्ट

stackoverflow.com/questions/2419598/why-might-different- पढ़ लिया है कंप्यूटर-गणना-अलग-अंकगणितीय-परिणाम-में-vb-net

(क्षमा करें, मेरे पास सामान्य लिंक के लिए पर्याप्त राइटिंग नहीं है)।

... लेकिन जानकारी को ठीक करने के बारे में जानकारी नहीं थी।


परियोजना वीएस 2015 कम्युनिटी संस्करण में ओएस विंडोज 7 के साथ मशीन पर .NET 4 क्लाइंट प्रोफ़ाइल के लिए संकलित की गई थी।

+0

छवियों को अपलोड करने के लिए आपको एक मुफ्त अपलोड सेवा चुननी चाहिए जिसके लिए हमें – TaW

+0

@TaW मूव छवि को imgur.com पर लॉग इन करने की आवश्यकता नहीं है और परीक्षण परियोजना को github –

+0

धन्यवाद पर ले जाएं। हालांकि मुझे लगता है कि लास का जवाब सही है: जेपीईजी पूर्ण सटीकता के साथ छवि को पुन: उत्पन्न करने के लिए नहीं है। यदि आपको वास्तव में इसकी ज़रूरत है तो पीएनजी में जाएं! – TaW

उत्तर

3

Wikipedia has this to say about the accuracy requirements for JPEG Decoders:

जेपीईजी में एन्कोडिंग वर्णन मानक परिशुद्धता उत्पादन संकुचित छवि के लिए आवश्यक का समाधान नहीं होता।हालांकि, जेपीईजी मानक (और इसी तरह के एमपीईजी मानकों) में डिकोडिंग प्रक्रिया के सभी हिस्सों (परिवर्तनीय लंबाई डीकोडिंग, उलटा डीसीटी, डिक्वेंटाइजेशन, आउटपुट का नवीकरण) सहित डीकोडिंग के लिए कुछ सटीक आवश्यकताओं को शामिल किया गया है; संदर्भ एल्गोरिथ्म से उत्पादन अधिक नहीं होनी चाहिए:

  • प्रत्येक पिक्सेल घटक के लिए अंतर का एक बिट की एक अधिकतम
  • प्रत्येक 8 × 8 पिक्सेल ब्लॉक
  • बहुत कम मतलब के ऊपर कम मतलब वर्ग त्रुटि प्रत्येक 8 × 8 पिक्सेल ब्लॉक
  • बहुत कम मतलब वर्ग पूर्ण छवि देखना
में पूरे छवि
  • बेहद कम मतलब त्रुटि से अधिक त्रुटि से अधिक त्रुटि (1 बिट
  • (मेरा जोर)

    संक्षेप में, वहाँ केवल दो अलग अलग विकोडक कार्यान्वयन खेल में यहाँ है, और वे विभिन्न छवियों का उत्पादन, सटीकता की आवश्यकता के भीतर = +/- 1 घटक में मूल्य, जैसा कि आपने देखा)।

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

    +0

    यह दुखद खबर है ... उत्तर के लिए Thanx। क्या आप पुस्तकालय जानते हैं जो पीएनजी, बीएमपी, जेपीईजी और टीआईएफएफ प्रारूपों के साथ मिलकर काम कर सकता है? –

    +0

    मैंने परियोजना के लिए बिटमैरेकल लिबपेग.NET लाइब्रेरी को जोड़ने की कोशिश की है और परिणाम ... –

    +1

    वैसे भी आपको प्लेटफॉर्म पर समान पिक्सेल बनाने के लिए इसकी आवश्यकता क्यों है? आप एक हानिकारक संपीड़न छवि प्रारूप का उपयोग कर रहे हैं, वैसे भी आपके पास पिक्सेल पर वास्तविक नियंत्रण नहीं है। –

    0

    मैं परियोजना और इस कोड को लिखने के लिए Libjpeg.NET जोड़कर मेरी समस्या का समाधान:

     private Bitmap JpegToBitmap(JpegImage jpeg) 
         { 
          int width = jpeg.Width; 
          int height = jpeg.Height; 
    
          // Read the image into the memory buffer 
          int[] raster = new int[height * width]; 
    
          for(int i = 0; i < height; ++i) 
          { 
           byte[] temp = jpeg.GetRow(i).ToBytes(); 
    
           for (int j = 0; j < temp.Length; j += 3) 
           { 
            int offset = i*width + j/3; 
            raster[offset] = 0; 
            raster[offset] |= (((int)temp[j+2]) << 16); 
            raster[offset] |= (((int)temp[j+1]) << 8); 
            raster[offset] |= (int)temp[j]; 
           } 
          } 
    
          Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb); 
          Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); 
          BitmapData bmpdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 
          byte[] bits = new byte[bmpdata.Stride * bmpdata.Height]; 
    
          for (int y = 0; y < bmp.Height; y++) 
          { 
           int rasterOffset = y * bmp.Width; 
           int bitsOffset = (bmp.Height - y - 1) * bmpdata.Stride; 
    
           for (int x = 0; x < bmp.Width; x++) 
           { 
            int rgba = raster[rasterOffset++]; 
            bits[bitsOffset++] = (byte)((rgba >> 16) & 0xff); 
            bits[bitsOffset++] = (byte)((rgba >> 8) & 0xff); 
            bits[bitsOffset++] = (byte)(rgba & 0xff); 
           } 
          } 
          System.Runtime.InteropServices.Marshal.Copy(bits, 0, bmpdata.Scan0, bits.Length); 
          bmp.UnlockBits(bmpdata); 
    
          return bmp; 
         } 
    

    तो, कि मेरे लिए काफी है।

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