Windows küçük resimlerini tekrarlı bir şekilde otomatik olarak nasıl oluşturabilirim? [çift]


6

Windows Gezgini ile Windows 8.1 kullanıyorum. Görüntü önbelleği ("thumbs.db"), video, fotoğraf veya benzeri dosyaları içeren bir klasörü ziyaret ettiğimde oluşturulur. Bununla ilgili bir sorunum var çünkü sürekli değişen değişen videolar ve fotoğraflar içeren birden fazla klasörüm var. Bu dosyaları içeren bir klasörü her açtığımda, küçük resim önbelleği oluşturulana kadar birkaç saniye beklemem gerekiyor.

Bir geçici çözüm, küçük resim önbelleğini devre dışı bırakmak olabilir. Ama küçük resimleri görmeyi seviyorum, bu yüzden bu benim için bir çözüm değil. Bunun yerine, tekrar tekrar Windows küçük resimlerini oluşturan her x saniyede bir toplu iş veya başka bir program çağırmak istiyorum. Daha sonra klasörleri gecikmeden açabildim.

Bunu nasıl başarabilirim?


Bu çözüm tek bir dizindeki resimler için çalışır. Neden alt dizinlerde de işe yaramayacağını anlamıyorum.
Vinayak

Dosyaları arka planda bir klasöre ekledikten sonra önbellek güncellemesi gerekiyor. Bu yalnızca Explorer’daki klasörü ziyaret ettikten sonra yapılacaktır. Bu yüzden bazı klasörlerin önbelleklerini (tekrarlı olarak) tanımlanmış bir gecikmeyle güncelleyecek bir komut dosyasına ihtiyacım var.
dude

Hepsini listelemek için kök dizinden görüntü ve video biçimlerini arayabilirsiniz. Sonuçlar arasında gezinmeye gelince, bu basit bir şekilde elde edilebilir AutoIt komut dosyası gönderir Sayfa Aşağı tuşu ( {PGDOWN} ) tekrar tekrar bir döngüde.
Vinayak

Yukarıdakilerin hepsini yapan bir AutoIT betiği oluşturabilir ve çalışmasını planlayabilir, her otuz dakikada bir söyleyebilirsiniz. Veya elle tetikleyebilirsin.
Vinayak

İşi yapmak için bu aracı buldum: bruhov.com/WinThumbsPreloader/en
Sunny127

Yanıtlar:


1

İşte ihtiyacınız olanı yapması gereken bir PowerShell betiği yazdım.

Mantığı bu konudan aldım: https://stackoverflow.com/questions/3555799/how-do-i-refresh-a-files-thumbnail-in-windows-explorer ve bunu Windows'ta zamanlanmış bir görev olarak çalıştırabileceğiniz bir komut dosyasına dönüştürdü.

Kullanmak için .net4.0 ve PowerShell 3.0 kurulu olmalıdır, aksi takdirde hatalarınız olur. Bu noktada muhtemelen .net4.0'a sahipsiniz, ancak muhtemelen ihtiyacınız olacak PowerShell 3.0

Aşağıdakileri thumb_generate.ps1 adlı bir dosyaya kaydedin.

param ([string]$path,[string]$ext)
function Refresh-Explorer 
{  
   $code = @'  
   [System.Runtime.InteropServices.DllImport("Shell32.dll")]   
   public static extern Int32 SHParseDisplayName([MarshalAs(UnmanagedType.LPWStr)] String pszName, IntPtr pbc, out IntPtr ppidl, UInt32 sfgaoIn, out UInt32 psfgaoOut);

   [System.Runtime.InteropServices.DllImport("Shell32.dll")]   
   private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);

   [System.Runtime.InteropServices.DllImport("Shell32.dll")]   
   private static extern int ILFree(IntPtr pidl);    

   public static void Refresh(string path)  {
    uint iAttribute;
    IntPtr pidl;
    SHParseDisplayName(path, IntPtr.Zero, out pidl, 0, out iAttribute);  
    SHChangeNotify(0x00002000, 0x1000, IntPtr.Zero, IntPtr.Zero); 
    ILFree(pidl); 
}  
'@  

    Add-Type -MemberDefinition $code -Namespace MyWinAPI -Name Explorer   
    [MyWinAPI.Explorer]::Refresh($path)  
} 

cls
if([System.String]::IsNullOrEmpty($path))
{
   Write-Host "Path cannot be empty."
   Write-Host "Example:  .\thumb_generate.ps1 -path ""C:\"" -ext ""jpg"""
   return
}
if([System.String]::IsNullOrEmpty($path))
{
   Write-Host "Extension cannot be empty."
   Write-Host "Example:  .\thumb_generate.ps1 -path ""C:\"" -ext ""jpg"""
   return
}

$fileExtension = "*." + $ext
Write-Host -ForegroundColor Green "---Thumbnail generation for Windows 7/8---"
Write-Host -ForegroundColor Green "----PowerShell 3.0 & .Net 4.0 required----"
Write-Host "Path: "  $path
Write-Host "Extension: " $fileExtension
Write-Host 
if (Test-Path $path) 
{
   Write-Host "Path Exists, begin generation thumbnails"

   $images = [System.IO.Directory]::EnumerateFiles($path,$fileExtension,"AllDirectories")
   Foreach($image in $images)
   {
       try
       {
          $file = New-Object System.IO.FileInfo($image)
          Write-Host $file.FullName
          $fStream = $file.Open([System.IO.FileMode]::Open,[System.IO.FileAccess]::Read,[System.IO.FileShare]::None)

          $firstbyte = New-Object Byte[] 1
          $result = $fStream.Read($firstbyte,0,1)
       }
       catch
       {
          Write-Host -ForegroundColor Red "An error occured on file: " + $file.FullName
       }
       $fStream.Close();
   }
    Refresh-Explorer
}
else
{
  "Path Doesn't Exist, Exiting..."
}

Ardından PowerShell komut satırından aşağıdaki parametrelerle yürütün:

.\thumb_generate.ps1 -path "C:\PathToImages\"  -ext "jpg"

Gerçekte, herhangi bir dosya uzantısı çalışmalıdır. Tüm dizinleri tekrarlayarak aşağı bakacak. Tek dezavantajı bir seferde yalnızca bir dosya türüdür, ancak yalnızca farklı bir dosya uzantısı kullanan birden fazla iş çalıştırılabilir. Temel olarak, komut dosyası her dosyayı açar ve yalnızca thumbs.db dosyasını güncellemeye zorlamak için yeterli olan ilk baytı okur.

Düzenle Komut dosyasını yukarıda da yayınlanan kabuk güncelleme bölümünü içerecek şekilde değiştirdim. Benim sistemimde çalışıyor gibi gözüküyor, ancak test edilecek binlerce imge yok. Bu, dosyanın ilk birkaç baytının her ikisinin de okumasını ve ardından küçük resimlerin yenilenmesini zorlar.


Teşekkür ederim. Bunu deneyeceğim. Ancak bunu Windows'ta bir cronjob'da çalıştırmam gerekiyor, böylece komut dosyasını manuel olarak çağırmam gerekmiyor. Bu, Windows görevleriyle uyumlu mu?
dude

2

Küçük resim oluşturmayı hızlandırmak için iki yöntem düşünebilirim:

  1. Küçük resmin boyutunu azaltın ( Daha fazla bilgi )
  2. Yeni dosyaların minik resimlerini periyodik olarak yenileyen bir program yazın.

İkinci yöntem için, bunu yapan bir ürün bilmiyorum, bu yüzden kendiniz yazmanız gerekecek. İşte faydalı bir referans: Windows Gezgini'nde bir dosyanın küçük resmini nasıl yenileyebilirim? .

Gönderi, bunu gerçekleştiren bir C # programının kaynağını önerir ve içerir. dosyanın ilk baytı okunuyor. Program dosyayı kapattığında Windows küçük resmi yeniler.

Kabul edilen cevap daha basit bir şekilde Windows'a dosyanın değiştiğini bildirir bir yayınlanan çözüm bu dosyayı okumak zorunda değil.

Sürümüm (denenmemiş):

public static void refreshThumbnail(string path)
{
    try
    {
        uint iAttribute;
        IntPtr pidl;
        SHParseDisplayName(path, IntPtr.Zero, out pidl, 0, out iAttribute);
        SHChangeNotify(
            (uint)ShellChangeNotificationEvents.SHCNE_UPDATEITEM,
            (uint)ShellChangeNotificationFlags.SHCNF_FLUSH,
            pidl,
            IntPtr.Zero);
        ILFree(pidl);

    }
    catch { }
}

Bu harika bilgiler için teşekkürler. Komut dosyanızı / bağlantılı komut dosyasını bir Windows konsolundan çalıştırmasını nasıl sağlayabilirim? Main () - işlevi olmadığından işe yarayıp yaramayacağından emin değilim.
dude

Bu aynı zamanda sadece C işlevi örneğidir.
Overmind

Evet, bu sadece yazılması gereken bir programda kullanılacak bir kod parçası.
harrymc

Küçük resmin güncellenip güncellenmediği nasıl kontrol edilir? Çünkü PowerShell'deki örnekten gelen C # kodunu kullanmaya çalıştım. refreshThumbnail Bu yöntem, küçük resimleri güncellemiyor gibi görünüyor. Kullandım bu araç Küçük resim önbelleğini görüntülemek için güncelleyin. F5 Explorer'dan iyi çalışıyor. Herhangi bir fikir?
beatcracker

Bir fikir, bağlı olduğum makalede olduğu gibi, belki de SHChangeNotify çağrısından sonra ve ek olarak, ilk baytı dosyadan okumak olacaktır. Belki bu, Windows'u çalışmalarını yapmaya ikna edecektir. Hiçbir şey işe yaramazsa, thumbs.db'yi güncelleyen Explorer'ın kendisidir, bu nedenle tek çözüm periyodik olarak F5'i yapan gizli bir Explorer örneği oluşturmak olacaktır (autohotkey bunu yapabilir).
harrymc

1

Bu başka bir program parçası meli IThumbnailCache COM arabirimini (C ++) kullanarak küçük resim önbelleğini yenileyin. Bildiğim kadarıyla, görev için önceden derlenmiş herhangi bir araç yok.

MSDN şöyle diyor: "IThumbnailCache :: GetThumbnail için flags parametresi WTS_EXTRACT bayrağını içeriyorsa ve küçük resim zaten önbelleğe alınmamışsa, küçük resim ayıklanacak ve önbelleğe yerleştirilecektir"

CoInitialize(NULL);

IThumbnailCache *cache;
HRESULT hr = CoCreateInstance(CLSID_LocalThumbnailCache, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&cache));
if (SUCCEEDED(hr))
{
    <loop over files>
    {
        cache->GetThumbnail(<shell item for file>, <required size>, WTS_EXTRACT, NULL, NULL, NULL);
        cache->Release();
    }
}

-2

Sorun oldukça karmaşık. Yapılacak en iyi şey, özellikle bu amaç için bir uygulama tasarlamaktır.

Seçenek 1:

* .Jpg, * .avi, vb. Aratın ve hepsi önbelleğe alınmalıdır.

Seçenek 2a:

Küçük resimleri el ile oluşturmak için bir toplu iş komut dosyası oluşturun. Örnek (ihtiyaçlarınıza uyarlayın):

mkdir thumbjunk
for f in *.jpg
do convert $f -thumbnail 100x80 thumbjunk/$f.gif

recursively:

find * -prune -name '*.jpg' \
-exec convert '{}' -thumbnail 100x80 thumbjunk/'{}'.gif 

Seçenek 2b:

Bu video dosyaları için, ffmpeg aracıdır.

Örnek:

ffmpeg -ss 00:01:00 -i testavi.avi -vf 'select=not(mod(n\,1000)),scale=320:240,tile=2x3' testavi.png

Seçenek 2 için, üretilen çıktınızın geçerli sayılması için başparmak adlandırma düzenine uymanız gerekir.


2
OP, küçük resimler önbelleğinin güncellenmesini istiyor, ayrı başparmak üretmiyor. Ayrıca, bundan bahsetmelisin convert bir ImageMagick aracı .
Vinayak

Evet, bahsetmeyi unuttum, dönüştürmek harici bir araçtır. Başka alternatifleri de var. Sistemime entegre olmaya alıştım.
Overmind

Evet, farklı klasörlerde küçük resimleri yeniden oluşturmayan önbelleği güncellemek istiyorum.
dude

Ayrıca, komut dosyası bir toplu iş komut dosyası gibi görünmüyor. Nasıl kullanıyorsun $f Parti halinde?
Vinayak

2
@Overmind Bu sorunun etiketlendiğinden bahsettim windows biri Windows sistemlerinde çalışan cevaplar beklerdi.
Vinayak
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.