質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
VB

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

1922閲覧

画像を魚眼レンズ風に拡大できるようにしたいです

rarar

総合スコア8

VB

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2019/12/11 09:53

画像をマウスカーソルの下に拡大表示させるプログラムを何とか作ることができました
参考にしたサイト
https://thinkit.co.jp/story/2013/11/11/4674

この拡大している画像を魚眼レンズ風の画像に変えたいです
どなたか知恵を貸してください

XAML

1<Window x:Class="MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="1080" Width="1920" WindowState="Maximized"> 5 <Canvas Margin="0,0,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="1920" Height="1080"> 6 <Image x:Name="sourceImage" HorizontalAlignment="Stretch" Height="1080" VerticalAlignment="Stretch" Width="1920" Canvas.Top="0" Source="Image/S__82993161.jpg" Canvas.Left="0"/> 7 <Image x:Name="zoomImage" Stretch="Uniform" IsHitTestVisible="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="1900" Height="1085" Source="Image/S__82993161.jpg" Canvas.Left="10" Canvas.Top="-15"> 8 <Image.RenderTransform> 9 <ScaleTransform ScaleX="3" ScaleY="3"/> 10 </Image.RenderTransform> 11 <Image.Clip> 12 <EllipseGeometry x:Name="Lens" RadiusX="30" RadiusY="30" Center="0.0,0.0"> 13 <EllipseGeometry.Transform> 14 <TransformGroup> 15 <ScaleTransform ScaleX="1" ScaleY="1"/> 16 <SkewTransform /> 17 <RotateTransform/> 18 <TranslateTransform/> 19 </TransformGroup> 20 </EllipseGeometry.Transform> 21 </EllipseGeometry> 22 </Image.Clip> 23 </Image> 24 <InkPresenter Name="paintCanvas"/> 25 </Canvas> 26</Window>

vb

1Imports Leap 2Imports System.Windows.Ink 3Imports System 4Imports System.Windows 5Imports System.Windows.Input 6Imports System.Windows.Media.Imaging 7Imports System.Windows.Interop 8 9 10 11 12 13 14Class MainWindow 15 Private Declare Function SetCursorPos Lib "user32" (x As Integer, y As Integer) As Boolean 16 Private Declare Function apimouse_event Lib "user32" Alias "mouse_event" (ByVal dwFlags As Int32, ByVal dx As Int32, ByVal dy As Int32, ByVal cButtons As Int32, ByVal dwExtraInfo As Int32) As Boolean 17 Private Const MOUSEEVENTF_LEFTDOWN = &H2 18 Private Const MOUSEEVENTF_LEFTUP = &H4 19 Private Const MOUSEEVENTF_MOVE = &H1 20 Private leap As New Controller 21 Private touchIndicator As New DrawingAttributes 22 Private touchPoint As StylusPoint 23 Private tx As Double 24 Private ty As Double 25 Private x As Integer 26 Private y As Integer 27 Private ImageX As Double 28 Private ImageY As Double 29 'Private Index As Integer 30 Private windowWidth As Double = 1920 31 Private windowHeight As Double = 1080 32 33 'Private no As Integer 34 Private FingersCount As Integer 35 36 37 38 39 Private Sub sourceImage_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles sourceImage.MouseLeftButtonDown 40 zoomImage.Visibility = Windows.Visibility.Visible 41 ImageX = e.GetPosition(sourceImage).X 42 ImageY = e.GetPosition(sourceImage).Y 43 LensPosition(ImageX, ImageY) 44 End Sub 45 46 Private Sub sourceImage_MouseMove(sender As Object, e As MouseEventArgs) Handles sourceImage.MouseMove 47 ImageX = e.GetPosition(sourceImage).X 48 ImageY = e.GetPosition(sourceImage).Y 49 LensPosition(ImageX, ImageY) 50 End Sub 51 52 Private Sub sourceImage_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles sourceImage.MouseLeftButtonUp 53 zoomImage.Visibility = Windows.Visibility.Collapsed 54 End Sub 55 56 57 Private Sub LensPosition(x As Double, y As Double) 58 Lens.Center = New Point(ImageX, ImageY) 59 zoomImage.SetValue(Canvas.LeftProperty, ImageX - (ImageX * 3)) 60 zoomImage.SetValue(Canvas.TopProperty, ImageY - (ImageY * 3)) 61 62 End Sub 63 64 65End Class 66

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

少なくともxamlを数行足すって程度では、できそうにもないですね。
何かライブラリ等はないかなとも思いましたが、見つけられませんでした。

案1 OpenCV的なもので画像を加工して重ねる。
パフォーマンスもよさそうですし、コード量も少なそう。
(私は魚眼にする方法は知りません^^;)

案2 球に適当に切り出した画像をマテリアルにマップし続ける。
雑に試してみましたが、特に重くはならず使えなくはないって感じでした。
(自分でもよくわかっていない、雑なC#コードでよければ出せます)

参考コード追記


画像を加工パターン
OpenCVとかわからないですが、GitHubでピュアC#のものを見つけたので試してみました。
AnthonyNystrom/GenXSource: Genetibase related source code (どういったリポジトリなのか全くわかってません^^;)

IFilter.cs
EffectFilter.cs
FishEye.cs
上記3つをプロジェクトに追加(ライセンスが明示されていないので注意してください)

xml

1<Window 2 x:Class="Questions228869.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Title="Fisheye" 6 MouseMove="Window_MouseMove" 7 SizeToContent="WidthAndHeight"> 8 <Window.Resources> 9 <BitmapImage x:Key="earthImage" UriSource="Image/1280px-Tissot_indicatrix_world_map_Lambert_cyl_equal-area_proj.svg.png" /> 10 </Window.Resources> 11 12 <Canvas Width="400" Height="300"> 13 <Image x:Name="sourceImage" Source="{StaticResource earthImage}" /> 14 <Image 15 x:Name="zoomImage" 16 Width="100" 17 Height="100" /> 18 19 </Canvas> 20</Window>

cs

1using System; 2using System.Windows; 3using System.Windows.Controls; 4using System.Windows.Input; 5using System.Windows.Media; 6using System.Windows.Media.Imaging; 7using Next2Friends.ImageWorks.EffectsFilters; 8 9namespace Questions228869 10{ 11 public partial class MainWindow : Window 12 { 13 private readonly RenderTargetBitmap inflateImage; 14 private const double offset = 200; 15 private int lastTimestamp; 16 17 public MainWindow() 18 { 19 InitializeComponent(); 20 21 // CroppedBitmapで例外が出るのでひと回り大きい画像を作る 22 var image = (BitmapImage)Resources["earthImage"]; 23 var visual = new DrawingVisual(); 24 var dc = visual.RenderOpen(); 25 var rect = new Rect(0, 0, image.PixelWidth + offset * 2, image.PixelHeight + offset * 2); 26 dc.DrawRectangle(Brushes.White, null, rect); 27 dc.DrawImage(image, new Rect(offset, offset, image.PixelWidth, image.PixelHeight)); 28 dc.Close(); 29 30 inflateImage = new RenderTargetBitmap((int)rect.Width, (int)rect.Height, 96, 96, PixelFormats.Pbgra32); 31 inflateImage.Render(visual); 32 } 33 34 private void Window_MouseMove(object sender, MouseEventArgs e) 35 { 36 // GCが走り続けて引っかかるので適当に間引く 37 if(Math.Abs(e.Timestamp - lastTimestamp) < 20) return; 38 lastTimestamp = e.Timestamp; 39 40 var p = e.GetPosition(sourceImage); 41 42 zoomImage.SetValue(Canvas.LeftProperty, p.X - zoomImage.Width / 2); 43 zoomImage.SetValue(Canvas.TopProperty, p.Y - zoomImage.Height / 2); 44 45 var ratioX = sourceImage.Source.Width / sourceImage.ActualWidth; 46 var ratioY = sourceImage.Source.Height / sourceImage.ActualHeight; 47 48 var sourceX = ratioX * p.X; 49 var sourceY = ratioY * p.Y; 50 51 var w = ratioX * zoomImage.Width; 52 var h = ratioY * zoomImage.Height; 53 var x = sourceX - w / 2 + offset; 54 var y = sourceY - h / 2 + offset; 55 var rect = new Int32Rect((int)x, (int)y, (int)w, (int)h); 56 try 57 { 58 var croppedBitmap = new CroppedBitmap(inflateImage, rect); 59 zoomImage.Source = new FisheyeFilter(0.1f).ExecuteFilter(croppedBitmap); 60 } 61 catch { /* NOP CroppedBitmapが範囲外 */ } 62 } 63 } 64}

使用感

  • 画像を凸に加工しているので境目が見えなくて見た目はよい。
  • GCが走り続けて引っかかるので、適度に間引いたところまあまあ使えるかなと(高速化の余地はまだまだあるので、不満ならどうにかなる)
  • 原寸表示だと1ドットの線とかが荒れがち。

イメージ説明

球体に貼るパターン
WPF で 3D(その5) : リード開発メモ
基本的にはここの通り。
Primitive3DSphere3Dをプロジェクトに追加、GetTextureCoordinateを修正(元ネタはMicrosoftのサンプル 解凍時に使用許諾が出るので確認してください)
xamlで書けることはできるだけ移したため、csは跡形ないです。

ほか参考にしたサイト WPF で地球を回してみるテスト - CX's Hatena Blog

xml

1<Window 2 x:Class="Questions228869.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Questions228869" 6 Title="Sphere3D" 7 MouseMove="Window_MouseMove" 8 SizeToContent="WidthAndHeight"> 9 <Window.Resources> 10 <BitmapImage x:Key="earthImage" UriSource="Image/1280px-Tissot_indicatrix_world_map_Lambert_cyl_equal-area_proj.svg.png" /> 11 </Window.Resources> 12 13 <Canvas Width="400" Height="300"> 14 <Image x:Name="sourceImage" Source="{StaticResource earthImage}" /> 15 <Viewport3D 16 x:Name="viewport" 17 Width="100" 18 Height="100"> 19 <Viewport3D.Camera> 20 <PerspectiveCamera 21 LookDirection="0,0,-1" 22 Position="0,0,3" 23 UpDirection="0,1,0" /> 24 </Viewport3D.Camera> 25 <ModelVisual3D> 26 <ModelVisual3D.Content> 27 <Model3DGroup> 28 <AmbientLight Color="#ffffff" /> 29 <DirectionalLight Direction="-1,-1,-1" Color="#ffffff" /> 30 </Model3DGroup> 31 </ModelVisual3D.Content> 32 </ModelVisual3D> 33 <local:Sphere3D x:Name="sphere" /> 34 </Viewport3D> 35 36 </Canvas> 37</Window>

cs

1using System; 2using System.Windows; 3using System.Windows.Controls; 4using System.Windows.Input; 5using System.Windows.Media; 6using System.Windows.Media.Imaging; 7using System.Windows.Media.Media3D; 8 9namespace Questions228869 10{ 11 public partial class MainWindow : Window 12 { 13 private readonly RenderTargetBitmap inflateImage; 14 // 倍率 それっぽくなるように現物合わせ 15 private const double scale = 0.85; 16 // 球に巻き始める余白部分 6時が正面とすると3時から反時計回り? 17 private const double offset = cropWidth / 4 * 3; 18 // 球に巻く画像の幅 高さから逆算 19 private const double cropWidth = Math.PI * cropHeight * scale; 20 // 球に巻く画像の高さ viewport.Height に合わせた 特に根拠なし 21 private const double cropHeight = 100 * scale; 22 23 public MainWindow() 24 { 25 InitializeComponent(); 26 27 // CroppedBitmapで例外が出るのでひと回り大きい画像を作る 28 // 上下右はもっと小さくていいが面倒なので全方向同じ数字で広げた 29 var image = (BitmapImage)Resources["earthImage"]; 30 var visual = new DrawingVisual(); 31 var dc = visual.RenderOpen(); 32 var rect = new Rect(0, 0, image.PixelWidth + offset * 2, image.PixelHeight + offset * 2); 33 dc.DrawRectangle(Brushes.White, null, rect); 34 dc.DrawImage(image, new Rect(offset, offset, image.PixelWidth, image.PixelHeight)); 35 dc.Close(); 36 37 inflateImage = new RenderTargetBitmap((int)rect.Width, (int)rect.Height, 96, 96, PixelFormats.Pbgra32); 38 inflateImage.Render(visual); 39 } 40 41 private void Window_MouseMove(object sender, MouseEventArgs e) 42 { 43 var p = e.GetPosition(sourceImage); 44 45 viewport.SetValue(Canvas.LeftProperty, p.X - viewport.Width / 2); 46 viewport.SetValue(Canvas.TopProperty, p.Y - viewport.Height / 2); 47 48 var ratioX = sourceImage.Source.Width / sourceImage.ActualWidth; 49 var ratioY = sourceImage.Source.Height / sourceImage.ActualHeight; 50 51 var sourceX = ratioX * p.X; 52 var sourceY = ratioY * p.Y; 53 54 var x = sourceX; // 巻き始め分を大きくしたのでちょうどxで合う 55 var y = sourceY - cropHeight / 2 + offset; 56 var rect = new Int32Rect((int)x, (int)y, (int)cropWidth, (int)cropHeight); 57 try 58 { 59 var croppedBitmap = new CroppedBitmap(inflateImage, rect); 60 sphere.Material = new DiffuseMaterial(new ImageBrush(croppedBitmap)); 61 } 62 catch { /* NOP CroppedBitmapが範囲外 */ } 63 } 64 } 65}

使用感

  • 球なので境目がわかってしまう。
  • パフォーマンスはよい(特に間引いていなくても普通に使えてる)
  • 大きさの調整等がめんどくさい。
  • 凸度?の調整が効かない。

イメージ説明

使用画像 1280x407 テイソーの指示楕円-ランベルト正積円筒図法の場合

投稿2019/12/11 14:40

編集2023/07/17 06:32
TN8001

総合スコア9244

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rarar

2019/12/16 07:04

ご丁寧にありがとうございます 試してみます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問