Alterando tamanho de arquivos depois da viagem


Todo mundo já passou por isso,,,  Depois de um passeio qualquer você e sua câmera chegam em casa e começa aquele martirio de passar as fotos da camera para o disco…

Quando você percebe tem uns poucos gigas de foto em um diretório qualquer…

propriedades

Ta certo que isso não representa muito,,, tenho 2TB no NAS justamente para armazenar coisas…

Mas para você, é bem provável que fique abrindo imagem por imagem no Paint e clicando em salvar uma a uma…

Pensando em diminuir um pouco esse trabalho, montei um script, em powershell, para fazer esse trabalho chato…

Ele até que é simples, vai procurar arquivo por arquivo dentro de um diretório e em seus sub-diretórios e vai tentar salvar o arquivo com um tamanho inferior na linha 16 está configurado o tamanho máximo do novo arquivo que ele vai respeitar,,, qualquer coisa superior a isso ele vai deixar o arquivo original…

ATENÇÃO:  uma coisa muito importante, eu testei esse arquivo em meu ambiente com as minhas fotos, eu sei o resultado que esperava e tenho backup. Antes de testar esse script em suas fotos faça uma cópia de algumas delas e execute o script. veja se o resultado esperado é satisfatório. Dependendo da foto ele reduz em alguns porcentos as dimensões da imagem, nada que tire a qualidade da imagem mas foi a forma do mecanismo em forçar a redução.

Vamos para parte que importa:

  1. Copie o código abaixo, ou baixe aqui.
  2. Crie um arquivo .PS1 no diretorio raiz onde estão suas fotos
  3. Abra o powershell em modo administratido e digite: Set-ExecutionPolicy -ExecutionPolicy unrestricted
    1. Isso libera a execução de arquivos .PS1 sem assinatura digital
  4. execute o arquivo .PS1

Como estava antes:

antes

A execução do PS1

ps

Como ficou depois:

depois

o código está abaixo, o download está aqui:

ATUALIZAÇÃO: Se vocês perceberam o código tem um pequeno BUG que pode atrapalhar um pouco a forma de armazenagem das fotos, na execução ele cria um novo arquivo e compara esse novo arquivo com o arquivo original, se a compressão funcionou ele remove o arquivo anterior e renomeia o novo arquivo para o nome antigo. Até aí sem problemas, o problema é que ele criou um arquivo, logo a data de criação e modificação são da data em que você executar o script. Para tentar resolver isso, adicionei duas linhas no código onde eu coloco em uma variável de data a informação com a data da última modificação (por que última modificação? porque se você mover o arquivo de lugar a data de criação é alterada) e outra linha no IF onde se o arquivo novo for menor que o arquivo original ele renomeia e troca a data de criação e modificação para a data do arquivo original.

Estou testando o script e até agora ele não falhou, caso encontrem algum bug o código está aí para ser alterado.


# Titulo: redutor de espaco ocupado por imagens jpg gif tif bmp
# Atencao: salve este arquivo com extensao .ps1 no diretorio raiz onde estao suas fotos
# abra o powershell e digite ” Set-ExecutionPolicy -ExecutionPolicy unrestricted “
# execute o arquivo que voce salvou com extensao .ps1 ele vai correr todos os arquivos no diretorio e sub-diretorio
#
# Execute este script por sua conta e risco,
# em todos os meus testes ele funcionou sem problemas mas nao quer dizer que ele vai funcionar em todos os ambientes.
#
# ricardo leka roveri
# http://leka.com.br
# @bigleka
# ricardo@leka.com.br

[reflection.assembly]::LoadWithPartialName(“System.Drawing”)

$SizeLimit=1280 # tamanho maximo que ele usa como limite
$logfile=”resizelog.txt” # Caso de erro ele gera um arquivo de relatorio
$toresize=$args[0] # lista de diretorio para localizar e modificar arquivos. pode deixar vazio

echo $toresize

$error.clear()

# primeira parte, localiza e altera arquivos jpg

Get-ChildItem -recurse $toresize -include *.jpg | foreach {
$OldBitmap = new-object System.Drawing.Bitmap $_.FullName # abre arquivo jpg
if ($error.count -ne 0) { # trata erro
$error | out-file $logfile -append -encoding default
$error[($error.count-1)].TargetObject | out-file $logfile -append -encoding default
echo $_>>$logfile
$error.clear()
}
$LongSide=$OldBitmap.Width # localiza as dimencoes
[datetime]$CreationDate=Get-ChildItem $_.FullName | Select-Object -ExpandProperty LastWriteTime # Armazena o campo da data de última modificação em uma variável para alterar a propriedade do novo arquivo
if ($OldBitmap.Width -lt $OldBitmap.Height) { $LongSide=$OldBitmap.Height }
if ($LongSide -gt $SizeLimit) { # se o arquivo localizado eh maior que o limite que voce configurou trabalha ele
if ($OldBitmap.Width -lt $OldBitmap.Height) { # calcula as dimencoes da figura
$newH=$SizeLimit
$newW=[int]($OldBitmap.Width*$SizeLimit/$OldBitmap.Height)
} else {
$newW=$SizeLimit
$newH=[int]($OldBitmap.Height*$newW/$OldBitmap.Width)
}
$NewBitmap = new-object System.Drawing.Bitmap $newW,$newH # cria o novo arquivo
$g=[System.Drawing.Graphics]::FromImage($NewBitmap)
$g.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic # utiliza algoritimo de alta qualidade
$g.DrawImage($OldBitmap, 0, 0, $newW, $newH) # redimensiona sua imagem

$name=$_.DirectoryName+”\”+$_.name+”.new” # gera um novo nome para a imagem
$NewBitmap.Save($name, ([system.drawing.imaging.imageformat]::jpeg)) # salva a nova imagem modificada
$NewBitmap.Dispose() # limpa a bagunca
$OldBitmap.Dispose()
$n=get-childitem $name
if ($n.length -ge $_.length) { # se o arquivo novo for maior que o arquivo original
Write-host -NoNewLine “+” # escreve um “+”
$n.delete() # e apaga ele
} else { # se o arquivo novo for menor que o origial
if ($n.Exists -and $_.Exists) {
$name=$_.FullName
$_.Delete() # apaga o original
$n.MoveTo($name) # renomeia o arquivo novo com o nome do arquivo original
Get-ChildItem $n | % { $_.CreationTime = $CreationDate } # utiliza a variável da data de modificação do arquivo original para alterar o campo da data de criação do novo arquivo
echo ($Name + ” ” + $LongSide) # escreve o nome na tela para fins didaticos
}
}

} else {
Write-host -NoNewLine “.”
$OldBitmap.Dispose()
}
}

# segunda parte, arquivos que nao sao jpg

Get-ChildItem -recurse $toresize -include *.bmp, *.tif, *.gif | foreach { # neste caso arquivos bmp, tif e gif
$OldBitmap = new-object System.Drawing.Bitmap $_.FullName
if ($error.count -ne 0) {
$error | out-file $logfile -append -encoding default
$error[($error.count-1)].TargetObject | out-file $logfile -append -encoding default
$error.clear()
}
$LongSide=$OldBitmap.Width
[datetime]$CreationDate=Get-ChildItem $_.FullName | Select-Object -ExpandProperty LastWriteTime
if ($OldBitmap.Width -lt $OldBitmap.Height) { $LongSide=$OldBitmap.Height }

if ($LongSide -gt $SizeLimit) {
if ($OldBitmap.Width -lt $OldBitmap.Height) {
$newH=$SizeLimit
$newW=[int]($OldBitmap.Width*$SizeLimit/$OldBitmap.Height)
} else {
$newW=$SizeLimit
$newH=[int]($OldBitmap.Height*$newW/$OldBitmap.Width)
}
$NewBitmap = new-object System.Drawing.Bitmap $newW,$newH
$g=[System.Drawing.Graphics]::FromImage($NewBitmap)
$g.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
$g.DrawImage($OldBitmap, 0, 0, $newW, $newH)

$name=$_.DirectoryName+”\”+$_.name.substring(0, $_.name.indexof($_.extension))+”.jpg” # gera um novo nome com extensao jpg
$NewBitmap.Save($name, ([system.drawing.imaging.imageformat]::jpeg)) # salva o novo arquivo
$NewBitmap.Dispose()
$OldBitmap.Dispose()
$n=get-childitem $name
if ($n.length -ge $_.length) {
$n.delete()
Write-host -NoNewLine “+”
} else {
echo ($Name + ” ” + $LongSide)
$_.Delete()
}
} else {
$name=$_.DirectoryName+”\”+$_.name.substring(0, $_.name.indexof($_.extension))+”.jpg”
$OldBitmap.Save($name, ([system.drawing.imaging.imageformat]::jpeg))
$OldBitmap.Dispose()
$n=get-childitem $name
if ($n.length -ge $_.length) {
$n.delete()
Write-host -NoNewLine “-“
} else {
Get-ChildItem $n | % { $_.CreationTime = $CreationDate }
echo ($Name + ” ” + $LongSide)
$_.Delete()
}
}
}

Logon automático para o w2k8


Acabei de colocar um post escrevendo como faz o logon automático para o w2k3 ai fui testar a mesma coisa no w2k8 e percebi que não havia a opção do Users must enter a user name and password to use this computer não aparecer mais,,, aahh isso só acontece depois que você coloca a maquina w2k8/7 no domínio…

Continuar lendo

Como criar um serviço,,,


Eu estava com uma necessidade interessante:
Como colocar um executável como serviço? sendo que esse executável é um programa em delphi que não foi projetado para ser um serviço.
Pesquisando um pouco achei uma documentação interessante:
http://support.microsoft.com/kb/137890/pt-br

Resumindo esse documento fiz o seguinte:

1º Instalei o Windows Resource Kit

2º pelo atalho do prompt criado pelo Resource Kit criei um atalho com o nome que eu queria. Ex: Instsrv.exe Nome_do_serviço “C:\Program Files\Resource Kit\Srvany.exe”

ATENÇÃO !!!
Esse Srvany.exe EXISTE, essa linha é assim mesmo, tem que criar desse jeito, esse executável deixa que você coloque qualquer aplicação para iniciar como serviço, nos próximos passos estou explicando onde você vai colocar o Executável que vai realmente iniciar o processo.

3º Após executar o passo 2 verifiquei que no registro foi criada uma entrada parecida com:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Nome_do_serviço

4º Dentro dessa chave Nome_do_Serviço, criei uma chave com o nome Parameters

5º Dentro de Parameters adicionei um registro do tipo REG_SZ com o nome Application, a sequência da chave contém o caminho do executável. Ex. C:\windows\notepad.exe

6º Fechei o Editor de Registro

7º Em Serviços já aparece o serviço que criei e é só iniciá-lo.

Simples e fácil.

Windows – Event 8: Failed auto update retrieval of third-party root list sequence number


Quando você está executado um Windows 2003 server sem conexão com a internet, você pode localizar o seguinte evento no seu eventlog:

—————–
Event Type: Error
Event Source: crypt32
Event Category: None
Event ID: 8
Date: date
Time: time
User: user name
Computer: computer name
Description:
Failed auto update retrieval of third-party root list sequence number from: with error: This operation returned because the timeout period expired.
For more information, see Help and Support Center at http://support.microsoft.com.
—————–

Para resolver isso, ou você tem acesso a internet ou remova o componente Update Root Certificates.

Para remover o componente faça o seguinte:
1. Vá em Add/Remove Programs (iniciar – executar – “appwiz.cpl”)
2. Click em Add/Remove Windows Components na esquerda.
3. Desmarque o Update Root Certificates, e termine o Windows Components Wizard.

Mais informações:
http://support.microsoft.com/kb/317541

Como habilitar o suporte do Windows Server Backup para Hyper-V VSS Writer


Olá,

Podemos fazer backup das maquinas virtuais utilizando habilitando VSS usando o Windows server Backup, para isso temos que adicionar a seguinte chave no registro:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\WindowsServerBackup\Application Support\{66841CD4-6DED-4F4B-8F17-FD23F8DDC3DE}
Após criar a chave vamos adicionar um String:
Nome: Application Identifier
Tipo: REG_SZ
valor: Hyper-V

Windows Server Backup suporta apenas backup de volumes, quando executar o backup das maquinas virtuais você precisa selecionar todos os volumes onde estão as maquinas virtuais.
Por exemplo, se você usa o local padrão para armazenar as configurações das maquinas virtuais (C:\ProgramData\Microsoft\Windows\Hyper-V\Virtual Machines) e armazena os VHD´s em outro volume, você precisa selecionar os 2 volumes para backup.

Quando for executar um Restore, selecione “Application Restore” e escolha Hyper-V. Você precisa selecionar esse método, caso contrário, você não conseguirá substituir os arquivos para as maquinas virtuais em execução. Como parte do restore, as maquinas virtuais existentes precisão ser desligadas e apagadas. As maquinas virtuais que você restaurar serão registradas no Hyper-V.

Existem algumas limitações:
1.- Maquinas virtuais que possuem discos dinâmicos não serão “backupeadas” usando o VSS. Apenas backup offline é suportado. Outra alternativa será utilizar o software de backup de dentro da própria maquina virtual como se fosse uma maquina física.
2.- Maquinas Virtuais Windows 2000, Windows XP ou que não possuem o Integration Services instalado, entrarão em Saved State enquanto o snapshot é tirado e voltarão a operar assim que o snapshot for completado. Você terá o mesmo incoveniente caso a opção de “Backup (volume snapshot)” esteja desabilitada das configurações da maquina virtual (Maquina Virtual >> Settings >> Management >> Integration Services)
3.- Quando executar um restore, todos os volumes serão restaurados, restaurar individualmente a maquina virtual não é suportado com o Windows server Backup.
4.- Se a maquina virtual possuir 2 ou mais snapshots, o restore irá falhar. Para resolver isso:
A. Se a maquina virtual estiver rodando, pare e apague a maquina virtual
B. Selecione a opção “Files and Folders” para recuperar o diretório de snapshot.
c. Selecione o diretório individual do snapshot
D. Quando completar, inicialize o a recuperação “Application” para recuperar o volume.

se tudo der certo você terá a maquina virtual de volta e operacional.