सफल डिकोडिंग image.Decode()
(और यह भी jpeg.Decode()
जैसे विशिष्ट डिकोडिंग कार्यों) image.Image
का मान प्रदान पर देना चाहिए। image.Image
एक इंटरफ़ेस है जो किसी छवि के केवल पढ़ने के दृश्य को परिभाषित करता है: यह छवि को बदलने/खींचने के तरीकों को प्रदान नहीं करता है।
image
पैकेज कई image.Image
कार्यान्वयन प्रदान करता है जो आपको छवि पर बदलने/खींचने की अनुमति देता है, आमतौर पर Set(x, y int, c color.Color)
विधि के साथ।
image.Decode()
हालांकि आप कभी भी गारंटी नहीं है कि वापस आ छवि छवि प्रकार image
पैकेज में निर्धारित किसी भी हो जाएगा नहीं देता है, या छवि के गतिशील प्रकार एक Set()
विधि (यह हो सकता है, लेकिन कोई गारंटी) है भी कि । पंजीकृत कस्टम छवि डिकोडर्स आपको image.Image
मान को कस्टम कार्यान्वयन के रूप में वापस कर सकते हैं (जिसका अर्थ है image
पैकेज में परिभाषित छवि प्रकार नहीं)।
यदि (गतिशील प्रकार की) छवि में Set()
विधि है, तो आप type assertion का उपयोग कर सकते हैं और इसे खींचने के लिए Set()
विधि का उपयोग कर सकते हैं।यह है कि यह कैसे किया जा सकता है है: छवि एक Set()
विधि नहीं है
type Changeable interface {
Set(x, y int, c color.Color)
}
imgfile, err := os.Open("unchanged.jpg")
if err != nil {
panic(err.Error())
}
defer imgfile.Close()
img, err := jpeg.Decode(imgfile)
if err != nil {
panic(err.Error())
}
if cimg, ok := img.(Changeable); ok {
// cimg is of type Changeable, you can call its Set() method (draw on it)
cimg.Set(0, 0, color.RGBA{85, 165, 34, 255})
cimg.Set(0, 1, color.RGBA{255, 0, 0, 255})
// when done, save img as usual
} else {
// No luck... see your options below
}
हैं, तो आप जो image.Image
लागू करता है एक कस्टम प्रकार को लागू करने से "अपने दृश्य को ओवरराइड" के लिए चुन सकते हैं, लेकिन इसकी At(x, y int) color.Color
विधि में (जो पिक्सेल के रंगों को वापस/आपूर्ति करता है) यदि आप छवि को बदल सकते हैं, तो आप नए रंगों को वापस कर देंगे, और मूल छवि के पिक्सल लौटाएंगे जहां आप छवि को नहीं बदलेंगे।
image.Image
इंटरफ़ेस को कार्यान्वित करना एम्बेड करके सबसे आसान किया जाता है, इसलिए आपको केवल इच्छित परिवर्तनों को लागू करने की आवश्यकता है। इस प्रकार यह किया जा सकता है:
type MyImg struct {
// Embed image.Image so MyImg will implement image.Image
// because fields and methods of Image will be promoted:
image.Image
}
func (m *MyImg) At(x, y int) color.Color {
// "Changed" part: custom colors for specific coordinates:
switch {
case x == 0 && y == 0:
return color.RGBA{85, 165, 34, 255}
case x == 0 && y == 1:
return color.RGBA{255, 0, 0, 255}
}
// "Unchanged" part: the colors of the original image:
return m.Image.At(x, y)
}
इसका उपयोग करना: बेहद सरल। छवि लोड के रूप में तुमने किया था, लेकिन जब बचत, जो बदल छवि सामग्री (रंग) जब यह एनकोडर से पूछा है प्रदान करने का ख्याल रखना होगा हमारे MyImg
प्रकार का एक मूल्य प्रदान करते हैं: आप के लिए है, तो
jpeg.Encode(outFile, &MyImg{img}, nil)
कई पिक्सेल बदलें, At()
विधि में सभी को शामिल करना व्यावहारिक नहीं है। इसके लिए हम अपने MyImg
का विस्तार कर सकते हैं ताकि हमारे Set()
कार्यान्वयन हो सकें जो पिक्सेल को संग्रहीत करता है जिसे हम बदलना चाहते हैं। उदाहरण कार्यान्वयन:
type MyImg struct {
image.Image
custom map[image.Point]color.Color
}
func NewMyImg(img image.Image) *MyImg {
return &MyImg{img, map[image.Point]color.Color{}}
}
func (m *MyImg) Set(x, y int, c color.Color) {
m.custom[image.Point{x, y}] = c
}
func (m *MyImg) At(x, y int) color.Color {
// Explicitly changed part: custom colors of the changed pixels:
if c := m.custom[image.Point{x, y}]; c != nil {
return c
}
// Unchanged part: colors of the original image:
return m.Image.At(x, y)
}
यह का उपयोग करना:
// Load image as usual, then
my := NewMyImg(img)
my.Set(0, 0, color.RGBA{85, 165, 34, 1})
my.Set(0, 1, color.RGBA{255, 0, 0, 255})
// And when saving, save 'my' instead of the original:
jpeg.Encode(outFile, my, nil)
आप अधिक से अधिक पिक्सेल बदलने के लिए है, तो यह अधिक लाभदायक हो सकता है सिर्फ एक नई छवि है जो अपनी पिक्सल को बदलने का समर्थन करता है बनाने के लिए है, उदा image.RGBA
, उस पर मूल छवि खींचें और फिर इच्छित पिक्सल को बदलने के लिए आगे बढ़ें।
किसी छवि को दूसरे पर आकर्षित करने के लिए, आप image/draw
पैकेज का उपयोग कर सकते हैं।
cimg := image.NewRGBA(img.Bounds())
draw.Draw(cimg, img.Bounds(), img, image.Point{}, draw.Over)
// Now you have cimg which contains the original image and is changeable
// (it has a Set() method)
cimg.Set(0, 0, color.RGBA{85, 165, 34, 255})
cimg.Set(0, 1, color.RGBA{255, 0, 0, 255})
// And when saving, save 'cimg' of course:
jpeg.Encode(outFile, cimg, nil)
उपरोक्त कोड केवल प्रदर्शन के लिए है। "वास्तविक जीवन" छवियों में Image.Bounds()
एक आयताकार वापस कर सकता है जो (0;0)
बिंदु से शुरू नहीं होता है, इस मामले में इसे कार्य करने के लिए कुछ समायोजन की आवश्यकता होगी।
संबंधित/संभावित डुप्लिकेट [गोलांग में एक आयत ड्रा करें?] (Http://stackoverflow.com/questions/28992396/draw-a-rectangle-in-golang) – icza
निष्पक्ष होने के लिए, मैं उस उत्तर को समझ नहीं पा रहा हूं। इसे दो बार पढ़ने के बाद भी मुझे नहीं पता कि सेट विधि का उपयोग करना कैसा है। –
ठीक है, नीचे मेरा जवाब देखें। – icza