কোডে ডাব্লুপিএফ চিত্র উত্স নির্ধারণ করা


325

আমি কোডে একটি WPF চিত্রের উত্স সেট করার চেষ্টা করছি। চিত্রটি প্রকল্পের একটি সংস্থান হিসাবে এম্বেড করা হয়েছে। উদাহরণগুলি দেখে আমি নীচের কোডটি নিয়ে এসেছি। কিছু কারণে এটি কাজ করে না - চিত্রটি প্রদর্শিত হবে না।

ডিবাগিংয়ের মাধ্যমে আমি দেখতে পাচ্ছি যে স্ট্রিমটিতে চিত্রের ডেটা রয়েছে। তাহলে কি সমস্যা?

Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream("SomeImage.png");
PngBitmapDecoder iconDecoder = new PngBitmapDecoder(iconStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
ImageSource iconSource = iconDecoder.Frames[0];
_icon.Source = iconSource;

আইকনটি এরকম কিছু সংজ্ঞায়িত করা হয়: <Image x:Name="_icon" Width="16" Height="16" />


চিত্রটি যদি কোনও স্থানীয় ড্রাইভে <Image Source="some_fully_qualified_path">থাকে তবে এক্সএএমএল-তে কখনই ব্যর্থ হয় না।
লরি স্টারন

@ লরিস্টিটারন পুরো বিষয়টি হ'ল এটি নির্ধারণের জন্য আমরা পথটি জানি না এবং কোডের প্রয়োজন নেই। উইন্ডোজ জিইউআই প্রোগ্রামিংয়ে কেউ নতুন হিসাবে, আমাকে স্বীকার করতে হবে যে উইনফর্মগুলি এই এক্সএএমএল ক্র্যাপের চেয়ে বেশি আবেদনময়ী বলে মনে হচ্ছে।
অ্যালেক্স জানসেন

উত্তর:


415

আপনার মতো একই সমস্যা হওয়ার পরে এবং কিছু পড়ার পরে, আমি সমাধানটি প্যাক ইউআরআই আবিষ্কার করেছি ।

আমি কোডে নিম্নলিখিতটি করেছি:

Image finalImage = new Image();
finalImage.Width = 80;
...
BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png");
logo.EndInit();
...
finalImage.Source = logo;

বা সংক্ষিপ্ততর, অন্য বিটম্যাপ ইমেজ নির্মাণকারী ব্যবহার করে:

finalImage.Source = new BitmapImage(
    new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png"));

ইউআরআই ভাগ করে নেওয়া হয়েছে:

  • কর্তৃপক্ষ: application:///
  • পথ: একটি উত্সাহিত সমাবেশে সংকলিত একটি সংস্থান ফাইলের নাম। পাথটি অবশ্যই নিম্নলিখিত ফর্ম্যাটকে মেনে চলতে হবে:AssemblyShortName[;Version][;PublicKey];component/Path

    • এসেম্বলশিয়ার্টনাম: রেফারেন্স অ্যাসেমব্লির সংক্ষিপ্ত নাম।
    • সংস্করণ [alচ্ছিক]: রেফারেন্স অ্যাসেমব্লির সংস্করণ যাতে সংস্থান ফাইল রয়েছে। একই সংক্ষিপ্ত নামের দুটি বা ততোধিক রেফারেন্সিয়াল সমাবেশগুলি লোড করা হলে এটি ব্যবহৃত হয়।
    • ; পাবলিকিকে [alচ্ছিক]: সর্বজনীন কী যা রেফারেন্সড অ্যাসেমব্লিকে স্বাক্ষর করতে ব্যবহৃত হত। একই সংক্ষিপ্ত নামের দুটি বা ততোধিক রেফারেন্সিয়াল সমাবেশগুলি লোড করা হলে এটি ব্যবহৃত হয়।
    • ; উপাদান: উল্লেখ করে যে সমাবেশটি উল্লেখ করা হচ্ছে তা স্থানীয় সমাবেশ থেকে উল্লেখ করা হয়েছে।
    • / পাথ: উল্লেখযোগ্য সমাবেশের প্রকল্প ফোল্ডারের মূলের সাথে সম্পর্কিত, তার পাথ সহ উত্স ফাইলের নাম।

তিনটি স্ল্যাশ পরে application:কমা দিয়ে প্রতিস্থাপন করতে হবে:

দ্রষ্টব্য: একটি প্যাক ইউআরআই এর কর্তৃত্ব উপাদান হ'ল একটি এমবেডেড ইউআরআই যা কোনও প্যাকেজকে নির্দেশ করে এবং অবশ্যই আরএফসি 2396 এর সাথে সামঞ্জস্য হয়। অতিরিক্ত হিসাবে, "/" অক্ষরটি "," অক্ষর এবং "%" এর মতো সংরক্ষিত অক্ষরের সাথে প্রতিস্থাপন করতে হবে এবং "?" পালাতে হবে। বিস্তারিত জানতে ওপিসি দেখুন।

এবং অবশ্যই, নিশ্চিত হয়ে নিন যে আপনি নিজের চিত্রটিতে বিল্ড অ্যাকশন সেট করেছেন Resource


হ্যাঁ, কিছু সমাধান এবং ত্রুটির পরে আমি এই সমাধানটি পেয়েছি। পুরো ব্যাখ্যা জন্য ধন্যবাদ। উত্তর গৃহীত!
Torbjørn

যদিও কেন এটি প্রয়োজন হয়েছিল আমি জানি না, এবং অন্যান্য উত্তরগুলি কেন আমার পক্ষে কার্যকর হয়নি ...
Torbjørn

এটি এবং অন্যান্য প্রশ্নের অন্যান্য উত্তর আমার পক্ষে কার্যকর হয়নি। এই এক পুরোপুরি কাজ করে। ধন্যবাদ।
থমাস স্টক

9
ঠিক আছে, তবে এক্সএএমএল পার্সার সরল পাথের স্ট্রিংটিকে ইমেজসোর্সে রূপান্তর করতে ব্যবহার করে এমন কোনও পদ্ধতি বা শ্রেণি নেই? আমরা কি কেবল এটি ব্যবহার করতে পারি না?
কিওয়ারটি

1
আমি প্রায়শই দেখতে পাই এই স্নিপেটটি অন্যান্য পোস্টে অনুলিপি করা হয়েছে, যেখানে লোকেরা সাধারণত BitmapImage(Uri)নির্মাণকারীর অস্তিত্ব উপেক্ষা করে , যা বিগিনিইনাইট এবং এন্ডআইনিট কল করার প্রয়োজনীয়তা এড়াতে সহায়তা করে। আমি এখানে এটি যুক্ত করেছি।
ক্লিমেন্স

175
var uriSource = new Uri(@"/WpfApplication1;component/Images/Untitled.png", UriKind.Relative);
foo.Source = new BitmapImage(uriSource);

এটি "চিত্রশক্তি" নামে একটি ফোল্ডারে "শিরোনামহীন.পিএনজি" নামে একটি চিত্র লোড করবে যার "বিল্ড অ্যাকশন" "WpfApplication1" নামক একটি সমাবেশে "রিসোর্স" এ সেট করা আছে।


16
তার জন্য ধন্যবাদ. একটি বিষয় যা আমাকে ডাব্লুপিএফ হিসাবে নুব হিসাবে ছড়িয়ে দিয়েছে, কাজ করার জন্য চিত্রটিকে অবশ্যই উত্স হিসাবে চিহ্নিত করতে হবে।
si618

4
এই সমাধানটি আমাকে একটি ব্যাতিক্রম দিয়েছে তাই আমি জ্যারেড হার্লির সমাধানটি চেষ্টা করেছিলাম এবং এটি কার্যকর হয়েছে ...
সংগ্রাম নন্দখিল

2
সবসময় ব্যতিক্রম ছুড়ে ফেলে অন্য উদাহরণ - সবচেয়ে গুরুত্বপূর্ণ জিনিস "UriKind.RelativeOrAbsolute" হয়
সেভেন

9
var uriSource = new Uri("Images/Untitled.png", UriKind.Relative);যথেষ্ট হবে
হামজেহ সোবহ

... এবং আরও সহজ। ধন্যবাদ হামজেহ
পিস্টান

74

এটি কিছুটা কম কোড এবং একক লাইনে করা যায়।

string packUri = "pack://application:,,,/AssemblyName;component/Images/icon.png";
_image.Source = new ImageSourceConverter().ConvertFromString(packUri) as ImageSource;

8
নেট। নিজস্ব নিজস্ব প্রয়োগ
জোশকমলে

আমাদের যদি চিত্রের উচ্চতা এবং প্রস্থ অর্থাৎ আইকন.পিএনজি সেট করতে হয় তবে কী হবে? কারণ _image.height এবং _image.width ব্যবহার করে এটি চিত্রের উইন্ডোটিকে আসল চিত্র নয়, আইকন.পিএনজি সেট করে।
গোপনে

41

খুব সহজ:

মেনু আইটেমের চিত্রটি গতিশীলভাবে সেট করতে, কেবল নিম্নলিখিতটি করুন:

MyMenuItem.ImageSource = 
    new BitmapImage(new Uri("Resource/icon.ico",UriKind.Relative));

... যদিও "আইকন.ইকো" সর্বত্র অবস্থিত হতে পারে (বর্তমানে এটি 'সংস্থানসমূহ' ডিরেক্টরিতে অবস্থিত) এবং অবশ্যই সংস্থান হিসাবে সংযুক্ত থাকতে হবে ...


2
খাটো = আরও ভাল। যদিও আমি এটি "" / ফোল্ডার / চিত্র.png "হিসাবে সেট করতে হয়েছিল তবে এটি ঠিকঠাকভাবে কাজ করেছিল। ধন্যবাদ!
gjvdkamp

3
আমি যখন ইমেজসোর্সটি বরাদ্দ করি তখন এটি খালি দেখাচ্ছে :(
হ্যালোমিডিয়াজ

@ হালোমিডিয়াজ পথটি ভুল হতে পারে .... যেমন আপনার রিসোর্স রয়েছে তবে আপনি এটি লিখতে পারেন রিসোর্স
রাউজবিহ জারান্দি

এটি আমার পক্ষে কাজ করেছে এবং অন্যান্য উত্তরের নিখুঁত ইউআরআইয়ের চেয়ে অনেক বেশি সোজা।
সিসিলোক

16

আপনি এটিকে এক লাইনেও হ্রাস করতে পারেন। এটি আমার কোডের জন্য আমার প্রধান উইন্ডোর আইকনটি সেট করতে ব্যবহৃত হয়েছিল। এটি ধরে নিয়েছে যে .ico ফাইলটি সামগ্রী হিসাবে চিহ্নিত হয়েছে এবং আউটপুট ডিরেক্টরিতে অনুলিপি করা হচ্ছে।

 this.Icon = new BitmapImage(new Uri("Icon.ico", UriKind.Relative));


15

আপনি চেষ্টা করেছেন:

Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream("SomeImage.png");
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = iconStream;
bitmap.EndInit();
_icon.Source = bitmap;

13

এটা আমার পথ:

internal static class ResourceAccessor
{
    public static Uri Get(string resourcePath)
    {
        var uri = string.Format(
            "pack://application:,,,/{0};component/{1}"
            , Assembly.GetExecutingAssembly().GetName().Name
            , resourcePath
        );

        return new Uri(uri);
    }
}

ব্যবহার:

new BitmapImage(ResourceAccessor.Get("Images/1.png"))

8

এখানে উদাহরণ রয়েছে যা গতিশীলভাবে চিত্রের পথটি নির্ধারণ করে (উত্স হিসাবে নির্মাণের পরিবর্তে ডিস্কে কোথাও অবস্থিত চিত্র):

if (File.Exists(imagePath))
{
    // Create image element to set as icon on the menu element
    Image icon = new Image();
    BitmapImage bmImage = new BitmapImage();
    bmImage.BeginInit();
    bmImage.UriSource = new Uri(imagePath, UriKind.Absolute);
    bmImage.EndInit();
    icon.Source = bmImage;
    icon.MaxWidth = 25;
    item.Icon = icon;
}

আইকনগুলির প্রতিচ্ছবি ...

প্রথম চিন্তা, আপনি ভাববেন যে আইকন সম্পত্তি কেবল একটি ইমেজ থাকতে পারে। তবে এতে আসলে কিছু থাকতে পারে! আমি দুর্ঘটনাক্রমে এটি আবিষ্কার করেছি যখন আমি প্রোগ্রামের Imageসাথে একটি চিত্রের পথ সহ সম্পত্তিটিকে সরাসরি স্ট্রিংয়ে সেট করার চেষ্টা করেছি । ফলাফলটি এটি চিত্রটি দেখায় নি, তবে পথের আসল পাঠ্য!

এটি আইকনটির জন্য কোনও চিত্র তৈরি না করার বিকল্পের দিকে পরিচালিত করে, তবে একটি সাধারণ "আইকন" প্রদর্শন করার পরিবর্তে প্রতীক ফন্টের সাহায্যে পাঠ্য ব্যবহার করুন। নিম্নলিখিত উদাহরণটিতে উইংডিংস ফন্ট ব্যবহার করা হয়েছে যা "ফ্লপিডিস্ক" প্রতীক রয়েছে। এই প্রতীকটি সত্যই অক্ষর <, যার এক্সএএমএল-এর বিশেষ অর্থ রয়েছে, সুতরাং এর &lt;পরিবর্তে আমাদের এনকোডেড সংস্করণটি ব্যবহার করতে হবে। এটি স্বপ্নের মতো কাজ করে! নীচে মেনু আইটেমটিতে একটি আইকন হিসাবে একটি ফ্লপিডিস্ক প্রতীক দেখায়:

<MenuItem Name="mnuFileSave" Header="Save" Command="ApplicationCommands.Save">
  <MenuItem.Icon>
    <Label VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Wingdings">&lt;</Label>
  </MenuItem.Icon>
</MenuItem>

প্রশ্ন: " চিত্রটি প্রকল্পের একটি উত্স হিসাবে এম্বেড করা হয়েছে ", উত্তর দিন: " এখানে একটি উদাহরণ [চিত্রের জন্য] উত্স হিসাবে নির্মাণের পরিবর্তে ডিস্কে কোথাও অবস্থিত "।
মিনিট

7

যদি আপনার চিত্রটি কোনও রিসোর্সড অভিধানে সঞ্চিত থাকে তবে আপনি কেবল একটি লাইনের কোডের সাহায্যে এটি করতে পারেন:

MyImage.Source = MyImage.FindResource("MyImageKeyDictionary") as ImageSource;

6

একটি সহজ উপায় আছে। যদি চিত্রটি এক্সএএমএল-তে একটি উত্স হিসাবে লোড করা হয়, এবং প্রশ্নের মধ্যে কোডটি সেই এক্সএএমএল সামগ্রীটির জন্য কোড-পিছনে রয়েছে:

Uri iconUri = new Uri("pack://application:,,,/ImageNAme.ico", UriKind.RelativeOrAbsolute);
NotifyIcon.Icon = BitmapFrame.Create(iconUri);

4

ফ্রেমটি ভিজ্যুয়াল ব্রাশে রাখুন:

VisualBrush brush = new VisualBrush { TileMode = TileMode.None };

brush.Visual = frame;

brush.AlignmentX = AlignmentX.Center;
brush.AlignmentY = AlignmentY.Center;
brush.Stretch = Stretch.Uniform;

জ্যামিতি ড্রয়িংয়ে ভিজ্যুয়াল ব্রাশ রাখুন

GeometryDrawing drawing = new GeometryDrawing();

drawing.Brush = brush;

// Brush this in 1, 1 ratio
RectangleGeometry rect = new RectangleGeometry { Rect = new Rect(0, 0, 1, 1) };
drawing.Geometry = rect;

এখন জ্যামিতি অঙ্কনকে একটি অঙ্কন চিত্রটিতে রাখুন:

new DrawingImage(drawing);

আপনার ইমেজ উত্স এ রাখুন, এবং voilà!

আপনি এটি অনেক সহজ করতে পারলেও:

<Image>
    <Image.Source>
        <BitmapImage UriSource="/yourassembly;component/YourImage.PNG"></BitmapImage>
    </Image.Source>
</Image>

এবং কোডে:

BitmapImage image = new BitmapImage { UriSource="/yourassembly;component/YourImage.PNG" };

হাঃ হাঃ হাঃ! যখন আপনি প্রথমে এটি কঠিন করে তুলতে পারেন কেন এটি সহজ করবেন :) যদিও আমি গ্রহণ করার আগে আমি আপনার সহজ সমাধানটি চেষ্টা করব ...
Torbjørn

আসলে এটি আমাকে মোটেই সহায়তা করেনি। হয়তো আমি বোকা :( এই মুহূর্তে আরও ঘনিষ্ঠভাবে দেখার সময় নেই (পোষা প্রাণীর প্রকল্প)। আমি আবার ফিরে এলে এর জন্য আরও উত্তর চাই :)
Torbjørn

3

একটি সহজ উপায় আছে। যদি চিত্রটি এক্সএএমএল-তে একটি উত্স হিসাবে লোড করা হয়, এবং প্রশ্নে কোডটি সেই এক্সএএমএল এর কোডবিহাইড:

এখানে এক্সএএমএল ফাইলের জন্য রিসোর্স ডিকশনারি রয়েছে - আপনার কেবলমাত্র "লাইন পোস্টার ব্রাশ" কী ব্রাউজারের সাথে ইমেজব্রাশের যত্ন নেওয়া লাইন - বাকী কোডটি কেবল প্রসঙ্গ দেখানোর জন্য

<UserControl.Resources>
        <ResourceDictionary>
            <ImageBrush x:Key="PosterBrush" ImageSource="..\Resources\Images\EmptyPoster.jpg" Stretch="UniformToFill"/>

        </ResourceDictionary>
    </UserControl.Resources>

এখন, পিছনের কোডটিতে, আপনি কেবল এটি করতে পারেন

ImageBrush posterBrush = (ImageBrush)Resources["PosterBrush"];

2

রিসোর্স আইকন এবং চিত্রগুলিতে এম্বেড করা থেকে কীভাবে কোনও চিত্র লোড করবেন (আর্ট্রিকাসের সংশোধিত সংস্করণ):

মনে করুন আপনি কোনও ছবি সহ একটি বোতাম যুক্ত করতে চান। তোমার কি করা উচিত?

  1. প্রকল্পের ফোল্ডার আইকনগুলিতে যুক্ত করুন এবং এখানে ক্লিকমেমে ক্লিক করুন e
  2. 'ক্লিকমাই.পিএনজি' এর বৈশিষ্ট্যগুলিতে 'বিল্ড অ্যাকশন' 'রিসোর্স' এ সেট করুন
  3. ধরুন আপনার সংকলিত সমাবেশের নাম 'Company.ProductAs એવું.dll'।
  4. এখন সময়টি XAML এ আমাদের চিত্রটি লোড করার

    <Button Width="200" Height="70">
      <Button.Content>
        <StackPanel>
          <Image Width="20" Height="20">
            <Image.Source>
              <BitmapImage UriSource="/Company.ProductAssembly;component/Icons/ClickMe.png"></BitmapImage>
              </Image.Source>
          </Image>
          <TextBlock HorizontalAlignment="Center">Click me!</TextBlock>
        </StackPanel>
      </Button.Content>
    </Button>

সম্পন্ন.


2

আমি ডাব্লুপিএফ-এ নতুন, কিন্তু নেটও নেই।

নেট .৩.৫ (ভিজ্যুয়াল স্টুডিও 2010) -র একটি "ডাব্লুপিএফ কাস্টম কন্ট্রোল লাইব্রেরি প্রজেক্টে" পিএনজি ফাইল যুক্ত করার চেষ্টা করে এবং এটি চিত্র-উত্তরাধিকারসূত্রে নিয়ন্ত্রণের পটভূমি হিসাবে সেট করার জন্য আমি পাঁচ ঘন্টা ব্যয় করেছি।

ইউআরআইয়ের সাথে সম্পর্কিত কোনও কিছুই কাজ করেনি। আমি কেন ভাবতে পারি না কেন ইনটেলিসেন্সের মাধ্যমে কোনও উত্স ফাইল থেকে ইউআরআই পাওয়ার কোনও পদ্ধতি নেই, সম্ভবত:

Properties.Resources.ResourceManager.GetURI("my_image");

আমি প্রচুর ইউআরআই চেষ্টা করেছি এবং রিসোর্স ম্যানেজার এবং অ্যাসেম্বলির গেটম্যানিস্ট পদ্ধতিতে খেলেছি, তবে ব্যতিক্রম বা নূন্য মানগুলি ছিল।

এখানে আমি কোডটি পট করছি যা আমার পক্ষে কাজ করেছে:

// Convert the image in resources to a Stream
Stream ms = new MemoryStream()
Properties.Resources.MyImage.Save(ms, ImageFormat.Png);

// Create a BitmapImage with the stream.
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = ms;
bitmap.EndInit();

// Set as source
Source = bitmap;

3
আমি মনে করি সমস্যাটি হ'ল ডাব্লুপিএফ রিসেক্স ফাইলগুলিতে সংস্থান স্থাপনের traditionalতিহ্যগত পদ্ধতির পছন্দ করে না। পরিবর্তে আপনি সরাসরি আপনার প্রকল্পে চিত্রটি যুক্ত করার এবং এর বিল্ড অ্যাকশন সম্পত্তিটি রিসোর্সে সেট করার কথা। আমি জানি না যে দুটি পদ্ধতির মধ্যে পার্থক্য কী (শারীরিক ফাইলের ফর্ম্যাট ক্ষেত্রে)।
কিওয়ারটি

1
বিল্ড অ্যাকশনটি বিষয়বস্তু নিশ্চিত করুন
জেরি নিকসন

1

আপনার যদি ইতিমধ্যে একটি স্ট্রিম থাকে এবং ফর্ম্যাটটি জানা থাকে তবে আপনি এর মতো কিছু ব্যবহার করতে পারেন:

static ImageSource PngStreamToImageSource (Stream pngStream) {
    var decoder = new PngBitmapDecoder(pngStream,
        BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
    return decoder.Frames[0];
}

1

আপনি কিছুটা মিস করেছেন।

যে কোনও সমাবেশ থেকে এম্বেড হওয়া সংস্থান পেতে, আপনার ফাইলের নাম সহ আপনার সমাবেশের নামটি উল্লেখ করতে হবে যেমন আমি এখানে উল্লেখ করেছি:

Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream(asm.GetName().Name + "." + "Desert.jpg");
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = iconStream;
bitmap.EndInit();
image1.Source = bitmap;

বিগিনিট () WPF- এ বিদ্যমান বলে মনে হয় না।
মায়োসোটিস

এটা নীচের লিঙ্কটি প্রাপ্তিসাধ্য চেক msdn.microsoft.com/en-us/library/...
maulik kansara
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.